From 0d3a559c058aa995b7764d85b80df42f50324938 Mon Sep 17 00:00:00 2001 From: Chuck Hagenbuch Date: Sun, 3 Oct 2010 12:27:10 -0400 Subject: [PATCH] Remove unmaintained/dead applications --- babel/COPYING | 280 ----- babel/README | 86 -- babel/commit.php | 59 - babel/config/hooks.php.dist | 28 - babel/docs/CHANGES | 5 - babel/docs/CREDITS | 15 - babel/docs/TODO | 8 - babel/download.php | 50 - babel/edit.php | 108 -- babel/extract.php | 119 -- babel/index.php | 21 - babel/lib/Application.php | 76 -- babel/lib/Babel.php | 304 ----- babel/lib/Display.php | 136 -- babel/lib/Translate.php | 748 ----------- babel/lib/Translate_Help.php | 238 ---- babel/lib/base.php | 110 -- babel/locale/.htaccess | 1 - babel/locale/babel.pot | 563 --------- babel/locale/fr/LC_MESSAGES/babel.mo | Bin 157237 -> 0 bytes babel/locale/fr/LC_MESSAGES/babel.po | 493 -------- babel/make.php | 76 -- babel/reset.php | 53 - babel/stats.php | 120 -- babel/templates/common-header.inc | 25 - babel/templates/index.php | 78 -- babel/templates/layout.html | 14 - babel/themes/graphics/babel.png | Bin 702 -> 0 bytes babel/themes/graphics/checked.gif | Bin 75 -> 0 bytes babel/themes/graphics/config.png | Bin 846 -> 0 bytes babel/themes/graphics/down.png | Bin 503 -> 0 bytes babel/themes/graphics/edit.png | Bin 795 -> 0 bytes babel/themes/graphics/extract.png | Bin 815 -> 0 bytes babel/themes/graphics/list.png | Bin 1348 -> 0 bytes babel/themes/graphics/locked.png | Bin 702 -> 0 bytes babel/themes/graphics/make.png | Bin 602 -> 0 bytes babel/themes/graphics/sample.png | Bin 167 -> 0 bytes babel/themes/graphics/unchecked.gif | Bin 67 -> 0 bytes babel/themes/graphics/up.png | Bin 517 -> 0 bytes babel/themes/graphics/upload.png | Bin 946 -> 0 bytes babel/themes/graphics/view.png | Bin 1348 -> 0 bytes babel/upload.php | 66 - babel/view.php | 504 -------- babel/viewsource.php | 82 -- crumb/COPYING | 280 ----- crumb/LICENSE.ASL | 48 - crumb/LICENSE.BSDL | 24 - crumb/README | 86 -- crumb/addclient.php | 41 - crumb/config/conf.bak.php | 0 crumb/config/conf.php | 7 - crumb/config/conf.xml | 27 - crumb/config/prefs.php.dist | 21 - crumb/contactsearch.php | 34 - crumb/docs/CHANGES | 5 - crumb/docs/CREDITS | 24 - crumb/docs/INSTALL | 237 ---- crumb/docs/RELEASE_NOTES | 49 - crumb/docs/TODO | 5 - crumb/index.php | 11 - crumb/lib/Application.php | 16 - crumb/lib/Block/example.php | 43 - crumb/lib/Crumb.php | 29 - crumb/lib/Driver.php | 63 - crumb/lib/Driver/sql.php | 127 -- crumb/lib/Forms/AddClient.php | 77 -- crumb/lib/Forms/ContactSearch.php | 34 - crumb/lib/base.php | 39 - crumb/listclients.php | 21 - crumb/locale | 111 -- crumb/scripts/sql/crumb.sql | 9 - crumb/templates/common-header.inc | 29 - crumb/templates/menu.inc | 5 - crumb/themes/screen.css | 0 drag_n_drop_portal/block.php | 37 - drag_n_drop_portal/index.php | 63 - drag_n_drop_portal/js/portal.js | 366 ------ drag_n_drop_portal/js/portal_edit.js | 204 --- drag_n_drop_portal/lib/Block/Layout/View/js.php | 110 -- drag_n_drop_portal/params.php | 42 - drag_n_drop_portal/save.php | 33 - drag_n_drop_portal/select.php | 36 - drag_n_drop_portal/templates/portal/params.php | 37 - drag_n_drop_portal/themes/graphics/bottom_left.gif | Bin 90 -> 0 bytes .../themes/graphics/bottom_right.gif | Bin 339 -> 0 bytes drag_n_drop_portal/themes/graphics/delete.png | Bin 762 -> 0 bytes drag_n_drop_portal/themes/graphics/edit.png | Bin 705 -> 0 bytes drag_n_drop_portal/themes/graphics/minus.png | Bin 203 -> 0 bytes drag_n_drop_portal/themes/graphics/plus.png | Bin 229 -> 0 bytes drag_n_drop_portal/themes/graphics/reload.png | Bin 264 -> 0 bytes drag_n_drop_portal/themes/graphics/tooltip_bg.png | Bin 2364 -> 0 bytes drag_n_drop_portal/themes/graphics/top_left.gif | Bin 190 -> 0 bytes drag_n_drop_portal/themes/graphics/top_right.gif | Bin 1123 -> 0 bytes drag_n_drop_portal/themes/screen.css | 217 ---- fima/COPYING | 280 ----- fima/README | 85 -- fima/account.php | 229 ---- fima/accounts.php | 98 -- fima/config/.htaccess | 1 - fima/config/conf.xml | 26 - fima/config/menu.php.dist | 39 - fima/config/prefs.php.dist | 168 --- fima/config/report.php.dist | 13 - fima/data.php | 227 ---- fima/docs/CHANGES | 12 - fima/docs/CREDITS | 26 - fima/docs/INSTALL | 225 ---- fima/docs/RELEASE_NOTES | 37 - fima/docs/TODO | 9 - fima/index.php | 11 - fima/ledgers/create.php | 38 - fima/ledgers/delete.php | 53 - fima/ledgers/edit.php | 53 - fima/ledgers/index.php | 41 - fima/lib/Application.php | 74 -- fima/lib/Block/summary.php | 159 --- fima/lib/Block/tree_menu.php | 34 - fima/lib/Driver.php | 411 ------ fima/lib/Driver/sql.php | 1064 ---------------- fima/lib/Fima.php | 764 ------------ fima/lib/Forms/CreateLedger.php | 48 - fima/lib/Forms/DeleteLedger.php | 87 -- fima/lib/Forms/EditLedger.php | 54 - fima/lib/Forms/account.php | 183 --- fima/lib/Report.php | 186 --- fima/lib/Report/AccountOverview.php | 286 ----- fima/lib/Report/Analysis.php | 384 ------ fima/lib/Report/AssetOverview.php | 325 ----- fima/lib/Report/GeneralOverview.php | 266 ---- fima/lib/Report/PeriodOverview.php | 272 ---- fima/lib/Report/Trend.php | 323 ----- fima/lib/ReportGraph.php | 191 --- fima/lib/ReportGraph/Bar.php | 88 -- fima/lib/ReportGraph/Line.php | 86 -- fima/lib/ReportGraph/Pie.php | 87 -- fima/lib/UI/VarRenderer/fima.php | 67 - fima/lib/base.php | 53 - fima/locale/.htaccess | 1 - fima/locale/de/LC_MESSAGES/fima.mo | Bin 176647 -> 0 bytes fima/locale/de/LC_MESSAGES/fima.po | 1316 -------------------- fima/locale/de/help.xml | 403 ------ fima/locale/en/help.xml | 406 ------ fima/locale/fima.pot | 1302 ------------------- fima/postings.php | 733 ----------- fima/report.php | 180 --- fima/scripts/sql/fima.sql | 40 - fima/search.php | 80 -- fima/templates/accounts/accounts.inc | 55 - fima/templates/common-header.inc | 29 - fima/templates/data/export.inc | 18 - fima/templates/data/import.inc | 35 - fima/templates/ledgers_list.php | 39 - fima/templates/menu.inc | 41 - fima/templates/postings/actions.inc | 23 - fima/templates/postings/edit.inc | 55 - fima/templates/postings/empty.inc | 5 - fima/templates/postings/footer.inc | 5 - fima/templates/postings/header.inc | 39 - fima/templates/postings/javascript_edit.inc | 357 ------ fima/templates/postings/javascript_list.inc | 165 --- fima/templates/postings/javascript_shift.inc | 9 - fima/templates/postings/javascript_transfer.inc | 13 - fima/templates/postings/list.inc | 15 - fima/templates/postings/navbar.inc | 33 - fima/templates/postings/posting_footers.inc | 56 - fima/templates/postings/posting_headers.inc | 82 -- fima/templates/postings/shift.inc | 34 - fima/templates/postings/transfer.inc | 64 - fima/templates/reports/empty.inc | 2 - fima/templates/reports/graph.inc | 3 - fima/templates/reports/img.inc | 6 - fima/templates/reports/reports.inc | 107 -- fima/templates/reports/table.inc | 44 - fima/templates/search/search.inc | 109 -- fima/themes/bluewhite/screen.css | 0 fima/themes/graphics/accounts.png | Bin 295 -> 0 bytes fima/themes/graphics/accounts.psd | Bin 23579 -> 0 bytes fima/themes/graphics/add.png | Bin 527 -> 0 bytes fima/themes/graphics/asset.png | Bin 446 -> 0 bytes fima/themes/graphics/eoasset.png | Bin 446 -> 0 bytes fima/themes/graphics/eoexpense.png | Bin 240 -> 0 bytes fima/themes/graphics/eoincome.png | Bin 242 -> 0 bytes fima/themes/graphics/expense.png | Bin 354 -> 0 bytes fima/themes/graphics/fima.png | Bin 448 -> 0 bytes fima/themes/graphics/income.png | Bin 348 -> 0 bytes fima/themes/graphics/list.png | Bin 448 -> 0 bytes fima/themes/graphics/new-small.png | Bin 224 -> 0 bytes fima/themes/graphics/posting.psd | Bin 28838 -> 0 bytes fima/themes/graphics/report.png | Bin 582 -> 0 bytes fima/themes/graphics/reports.psd | Bin 24676 -> 0 bytes fima/themes/graphics/search-small.png | Bin 673 -> 0 bytes fima/themes/report.inc | 69 - fima/themes/screen.css | 291 ----- fima/themes/silver/graphics/accounts.png | Bin 541 -> 0 bytes fima/themes/silver/graphics/accounts.psd | Bin 24068 -> 0 bytes fima/themes/silver/graphics/add.png | Bin 762 -> 0 bytes fima/themes/silver/graphics/asset.png | Bin 732 -> 0 bytes fima/themes/silver/graphics/eoasset.png | Bin 732 -> 0 bytes fima/themes/silver/graphics/eoexpense.png | Bin 764 -> 0 bytes fima/themes/silver/graphics/eoincome.png | Bin 787 -> 0 bytes fima/themes/silver/graphics/expense.png | Bin 777 -> 0 bytes fima/themes/silver/graphics/fima.png | Bin 736 -> 0 bytes fima/themes/silver/graphics/income.png | Bin 793 -> 0 bytes fima/themes/silver/graphics/list.png | Bin 736 -> 0 bytes fima/themes/silver/graphics/new-small.png | Bin 242 -> 0 bytes fima/themes/silver/graphics/posting.psd | Bin 28490 -> 0 bytes fima/themes/silver/graphics/report.png | Bin 364 -> 0 bytes fima/themes/silver/graphics/report.psd | Bin 22810 -> 0 bytes fima/themes/silver/graphics/search-small.png | Bin 327 -> 0 bytes fima/themes/silver/screen.css | 0 flexdemo/alt.php | 13 - flexdemo/garland/app.html.php | 4 - flexdemo/garland/css/defaults-rtl.css | 7 - flexdemo/garland/css/defaults.css | 53 - flexdemo/garland/css/fix-ie-rtl.css | 63 - flexdemo/garland/css/fix-ie.css | 69 - flexdemo/garland/css/print.css | 55 - flexdemo/garland/css/style-rtl.css | 293 ----- flexdemo/garland/css/style.css | 1079 ---------------- flexdemo/garland/images/bg-bar-white.png | Bin 110 -> 0 bytes flexdemo/garland/images/bg-bar.png | Bin 125 -> 0 bytes flexdemo/garland/images/bg-content-left.png | Bin 3275 -> 0 bytes flexdemo/garland/images/bg-content-right.png | Bin 3169 -> 0 bytes flexdemo/garland/images/bg-content.png | Bin 485 -> 0 bytes .../garland/images/bg-navigation-item-hover.png | Bin 441 -> 0 bytes flexdemo/garland/images/bg-navigation-item.png | Bin 502 -> 0 bytes flexdemo/garland/images/bg-navigation.png | Bin 104 -> 0 bytes flexdemo/garland/images/bg-tab.png | Bin 115 -> 0 bytes flexdemo/garland/images/body.png | Bin 712 -> 0 bytes flexdemo/garland/images/gradient-inner.png | Bin 189 -> 0 bytes flexdemo/garland/images/menu-collapsed-rtl.gif | Bin 176 -> 0 bytes flexdemo/garland/images/menu-collapsed.gif | Bin 176 -> 0 bytes flexdemo/garland/images/menu-expanded.gif | Bin 183 -> 0 bytes flexdemo/garland/images/menu-leaf.gif | Bin 175 -> 0 bytes flexdemo/garland/images/task-list.png | Bin 128 -> 0 bytes flexdemo/garland/left.html.php | 4 - flexdemo/garland/list.html.php | 7 - flexdemo/garland/main.html.php | 54 - flexdemo/garland/right.html.php | 1 - flexdemo/garland/secondary.html.php | 58 - flexdemo/index.php | 13 - flexdemo/lib/Block/block1.php | 39 - flexdemo/lib/Block/block2.php | 39 - flexdemo/lib/Block/menu.php | 41 - jeta/COPYING | 280 ----- jeta/README | 83 -- jeta/config/.htaccess | 1 - jeta/config/conf.xml | 20 - jeta/config/prefs.php.dist | 229 ---- jeta/docs/CHANGES | 31 - jeta/docs/CREDITS | 27 - jeta/docs/INSTALL | 232 ---- jeta/docs/RELEASE_NOTES | 43 - jeta/index.php | 23 - .../SSHTermApplet-jdk1.3.1-dependencies-signed.jar | Bin 2053292 -> 0 bytes .../jar/SSHTermApplet-jdkbug-workaround-signed.jar | Bin 5318 -> 0 bytes jeta/jar/SSHTermApplet-signed.jar | Bin 996901 -> 0 bytes jeta/jar/jta.conf | 1 - jeta/jar/jta26.jar | Bin 248182 -> 0 bytes jeta/lib/.htaccess | 1 - jeta/lib/Applet.php | 72 -- jeta/lib/Applet/jta.php | 102 -- jeta/lib/Applet/sshtools.php | 92 -- jeta/lib/Application.php | 59 - jeta/lib/Test.php | 62 - jeta/locale/.htaccess | 1 - jeta/locale/cs/LC_MESSAGES/jeta.mo | Bin 139196 -> 0 bytes jeta/locale/cs/LC_MESSAGES/jeta.po | 18 - jeta/locale/de/LC_MESSAGES/jeta.mo | Bin 160961 -> 0 bytes jeta/locale/de/LC_MESSAGES/jeta.po | 177 --- jeta/locale/de/help.xml | 13 - jeta/locale/en/help.xml | 12 - jeta/locale/es/LC_MESSAGES/jeta.mo | Bin 153542 -> 0 bytes jeta/locale/es/LC_MESSAGES/jeta.po | 179 --- jeta/locale/es/help.xml | 10 - jeta/locale/fi/LC_MESSAGES/jeta.mo | Bin 147511 -> 0 bytes jeta/locale/fi/LC_MESSAGES/jeta.po | 15 - jeta/locale/jeta.pot | 171 --- jeta/locale/ro/LC_MESSAGES/jeta.mo | Bin 14946 -> 0 bytes jeta/locale/ro/LC_MESSAGES/jeta.po | 16 - jeta/locale/zh_TW/LC_MESSAGES/jeta.mo | Bin 139486 -> 0 bytes jeta/locale/zh_TW/LC_MESSAGES/jeta.po | 16 - jeta/templates/common-header.inc | 15 - jeta/templates/main.html | 6 - jeta/themes/graphics/favicon.ico | Bin 1150 -> 0 bytes jeta/themes/graphics/jeta.png | Bin 162 -> 0 bytes kastalia/COPYING | 280 ----- kastalia/LICENSE.ASL | 48 - kastalia/LICENSE.BSDL | 24 - kastalia/README | 56 - kastalia/config/.htaccess | 1 - kastalia/config/conf.php | 12 - kastalia/config/conf.xml | 36 - kastalia/datastore/.htaccess | 1 - kastalia/decrypt_menu.php | 104 -- kastalia/docs/CHANGES | 37 - kastalia/docs/CREDITS | 9 - kastalia/docs/INSTALL | 177 --- kastalia/docs/RELEASE_NOTES | 14 - kastalia/docs/TODO | 5 - kastalia/download.php | 159 --- kastalia/encrypt_decrypt_files.php | 383 ------ kastalia/index.php | 12 - kastalia/lib/Application.php | 16 - kastalia/lib/Block/tree_menu.php | 37 - kastalia/lib/Kastalia.php | 45 - kastalia/lib/base.php | 36 - kastalia/list.php | 18 - kastalia/locale/.htaccess | 1 - kastalia/locale/de/help.xml | 15 - kastalia/locale/en/help.xml | 13 - kastalia/locale/kastalia.pot | 29 - kastalia/main.php | 236 ---- kastalia/temp/.htaccess | 1 - kastalia/templates/common-footer.inc | 3 - kastalia/templates/common-header.inc | 32 - kastalia/templates/menu.inc | 5 - kastalia/themes/graphics/directory_closed.gif | Bin 278 -> 0 bytes kastalia/themes/graphics/directory_open.gif | Bin 210 -> 0 bytes kastalia/themes/graphics/file.gif | Bin 125 -> 0 bytes kastalia/themes/graphics/file_enc.gif | Bin 664 -> 0 bytes kastalia/themes/graphics/kastalia.png | Bin 451 -> 0 bytes kastalia/themes/graphics/loader.gif | Bin 7757 -> 0 bytes kastalia/themes/graphics/menu/upload.png | Bin 214 -> 0 bytes kastalia/themes/screen.css | 44 - kastalia/upload.php | 207 --- kastalia/upload_menu.php | 258 ---- news/add.php | 605 --------- news/admin/categories/delete.php | 41 - news/admin/categories/edit.php | 55 - news/admin/categories/index.php | 47 - news/admin/sources/delete.php | 42 - news/admin/sources/edit.php | 54 - news/admin/sources/index.php | 49 - news/admin/tabs.php | 23 - news/browse.php | 65 - news/cloud.php | 27 - news/config/conf.xml | 112 -- news/config/prefs.php.dist | 51 - news/content.php | 28 - news/content_edit.php | 33 - news/delete.php | 94 -- news/delete_file.php | 91 -- news/diff.php | 61 - news/edit.php | 205 --- news/feed.php | 37 - news/files.php | 125 -- news/index.php | 14 - news/js/feed.js | 25 - news/lib/Api.php | 102 -- news/lib/Application.php | 58 - news/lib/Block/categories.php | 34 - news/lib/Block/category.php | 65 - news/lib/Block/jonah.php | 58 - news/lib/Block/last.php | 62 - news/lib/Block/last_blogs.php | 48 - news/lib/Block/last_comments.php | 56 - news/lib/Block/most_commented.php | 55 - news/lib/Block/most_read.php | 55 - news/lib/Block/my_comments.php | 76 -- news/lib/Block/sources.php | 44 - news/lib/Block/tags_cloud.php | 38 - news/lib/Categories.php | 615 --------- news/lib/Driver.php | 77 -- news/lib/Driver/sql.php | 583 --------- news/lib/Forms/Search.php | 133 -- news/lib/News.php | 469 ------- news/lib/Search.php | 135 -- news/lib/TagCloud.php | 44 - news/lib/View.php | 74 -- news/lib/base.php | 50 - news/locale/.htaccess | 1 - news/locale/news.pot | 958 -------------- news/locale/sl/LC_MESSAGES/news.mo | Bin 137811 -> 0 bytes news/locale/sl/LC_MESSAGES/news.po | 949 -------------- news/mail.php | 62 - news/news.php | 54 - news/note.php | 43 - news/pdf.php | 60 - news/po/messages.mo | Bin 9367 -> 0 bytes news/print.php | 25 - news/reads.php | 49 - news/rss/comments.php | 51 - news/rss/index.php | 55 - news/rss/news.php | 80 -- news/scripts/sql/news.mysql.sql | 107 -- news/scripts/upgrades/20070302_trackback.sql | 13 - news/scripts/upgrades/20070609_sponsored.sql | 2 - news/scripts/upgrades/20071220_tags.sql | 1 - news/search.php | 63 - news/tags.php | 40 - news/templates/add/before.inc | 0 news/templates/block/news.php | 19 - news/templates/block/titles.php | 21 - news/templates/browse/footer.inc | 1 - news/templates/browse/header.inc | 3 - news/templates/browse/row.inc | 12 - news/templates/categories/delete.html | 9 - news/templates/categories/edit.html | 9 - news/templates/categories/index.html | 5 - news/templates/categories/index.php | 27 - news/templates/common-header.inc | 31 - news/templates/edit/footer.inc | 4 - news/templates/edit/header.inc | 17 - news/templates/edit/info.php | 124 -- news/templates/edit/row.php | 68 - news/templates/menu.inc | 14 - news/templates/news/attachments.php | 5 - news/templates/news/blog.php | 39 - news/templates/news/comments.php | 21 - news/templates/news/gallery.php | 19 - news/templates/news/info.php | 20 - news/templates/news/mail.php | 7 - news/templates/news/news.php | 46 - news/templates/news/parents.php | 12 - news/templates/news/selling.php | 13 - news/templates/news/threads.php | 14 - news/templates/news/today.php | 13 - news/templates/news/tools.php | 25 - news/templates/news/ulaform.php | 17 - news/templates/print/footer.inc | 0 news/templates/print/header.inc | 0 news/templates/reads/footer.inc | 1 - news/templates/reads/header.inc | 10 - news/templates/reads/row.inc | 6 - news/templates/sources/index.php | 18 - news/themes/graphics/folder_open.png | Bin 529 -> 0 bytes news/themes/graphics/mkdir.png | Bin 968 -> 0 bytes news/themes/graphics/news.png | Bin 613 -> 0 bytes news/themes/screen.css | 82 -- news/trackback.php | 90 -- skoli/LICENSE | 48 - skoli/README | 87 -- skoli/add.php | 43 - skoli/classes/create.php | 46 - skoli/classes/delete.php | 48 - skoli/classes/edit.php | 75 -- skoli/classes/index.php | 37 - skoli/config/conf.xml | 61 - skoli/config/prefs.php.dist | 205 --- skoli/config/schools.php.dist | 114 -- skoli/data.php | 178 --- skoli/docs/CHANGES | 5 - skoli/docs/CREDITS | 17 - skoli/docs/INSTALL | 241 ---- skoli/docs/RELEASE_NOTES | 52 - skoli/docs/TODO | 13 - skoli/entry.php | 118 -- skoli/index.php | 10 - skoli/lib/Ajax/Application.php | 15 - skoli/lib/Application.php | 16 - skoli/lib/Block/tree_menu.php | 62 - skoli/lib/Driver.php | 138 -- skoli/lib/Driver/sql.php | 605 --------- skoli/lib/Forms/CreateClass.php | 234 ---- skoli/lib/Forms/DeleteClass.php | 77 -- skoli/lib/Forms/EditClass.php | 169 --- skoli/lib/Forms/Entry.php | 184 --- skoli/lib/School.php | 287 ----- skoli/lib/Skoli.php | 1076 ---------------- skoli/lib/base.php | 37 - skoli/list.php | 159 --- skoli/locale/.htaccess | 1 - skoli/locale/de/LC_MESSAGES/skoli.mo | Bin 172277 -> 0 bytes skoli/locale/de/LC_MESSAGES/skoli.po | 1019 --------------- skoli/locale/de/help.xml | 16 - skoli/locale/en/help.xml | 16 - skoli/locale/skoli.pot | 996 --------------- skoli/scripts/.htaccess | 1 - skoli/scripts/sql/skoli.sql | 81 -- skoli/search.php | 187 --- skoli/templates/classes/list.php | 35 - skoli/templates/common-header.inc | 34 - skoli/templates/data/export.inc | 34 - skoli/templates/entry/delete.inc | 10 - skoli/templates/list/classes.inc | 49 - skoli/templates/list/empty.inc | 3 - skoli/templates/list/footers.inc | 6 - skoli/templates/list/header.inc | 10 - skoli/templates/list/headers.inc | 96 -- skoli/templates/list/students.inc | 51 - skoli/templates/menu.inc | 5 - skoli/templates/panel.inc | 76 -- skoli/templates/search/criteria.inc | 44 - skoli/templates/search/empty.inc | 3 - skoli/templates/search/entries.inc | 27 - skoli/templates/search/footers.inc | 6 - skoli/templates/search/header.inc | 11 - skoli/templates/search/headers.inc | 49 - skoli/themes/categoryCSS.php | 31 - skoli/themes/graphics/add.png | Bin 663 -> 0 bytes skoli/themes/graphics/az.png | Bin 117 -> 0 bytes skoli/themes/graphics/favicon.ico | Bin 792 -> 0 bytes skoli/themes/graphics/minus.png | Bin 203 -> 0 bytes skoli/themes/graphics/plus.png | Bin 229 -> 0 bytes skoli/themes/graphics/search.png | Bin 794 -> 0 bytes skoli/themes/graphics/skoli.png | Bin 767 -> 0 bytes skoli/themes/graphics/timetable.png | Bin 501 -> 0 bytes skoli/themes/graphics/za.png | Bin 119 -> 0 bytes skoli/themes/screen.css | 124 -- 500 files changed, 42521 deletions(-) delete mode 100644 babel/COPYING delete mode 100644 babel/README delete mode 100644 babel/commit.php delete mode 100644 babel/config/hooks.php.dist delete mode 100644 babel/docs/CHANGES delete mode 100644 babel/docs/CREDITS delete mode 100644 babel/docs/TODO delete mode 100644 babel/download.php delete mode 100644 babel/edit.php delete mode 100644 babel/extract.php delete mode 100644 babel/index.php delete mode 100644 babel/lib/Application.php delete mode 100644 babel/lib/Babel.php delete mode 100644 babel/lib/Display.php delete mode 100644 babel/lib/Translate.php delete mode 100644 babel/lib/Translate_Help.php delete mode 100644 babel/lib/base.php delete mode 100644 babel/locale/.htaccess delete mode 100644 babel/locale/babel.pot delete mode 100644 babel/locale/fr/LC_MESSAGES/babel.mo delete mode 100644 babel/locale/fr/LC_MESSAGES/babel.po delete mode 100644 babel/make.php delete mode 100644 babel/reset.php delete mode 100644 babel/stats.php delete mode 100644 babel/templates/common-header.inc delete mode 100644 babel/templates/index.php delete mode 100644 babel/templates/layout.html delete mode 100644 babel/themes/graphics/babel.png delete mode 100644 babel/themes/graphics/checked.gif delete mode 100644 babel/themes/graphics/config.png delete mode 100644 babel/themes/graphics/down.png delete mode 100644 babel/themes/graphics/edit.png delete mode 100644 babel/themes/graphics/extract.png delete mode 100644 babel/themes/graphics/list.png delete mode 100644 babel/themes/graphics/locked.png delete mode 100644 babel/themes/graphics/make.png delete mode 100644 babel/themes/graphics/sample.png delete mode 100644 babel/themes/graphics/unchecked.gif delete mode 100644 babel/themes/graphics/up.png delete mode 100644 babel/themes/graphics/upload.png delete mode 100644 babel/themes/graphics/view.png delete mode 100644 babel/upload.php delete mode 100644 babel/view.php delete mode 100644 babel/viewsource.php delete mode 100644 crumb/COPYING delete mode 100644 crumb/LICENSE.ASL delete mode 100644 crumb/LICENSE.BSDL delete mode 100644 crumb/README delete mode 100644 crumb/addclient.php delete mode 100644 crumb/config/conf.bak.php delete mode 100644 crumb/config/conf.php delete mode 100644 crumb/config/conf.xml delete mode 100644 crumb/config/prefs.php.dist delete mode 100644 crumb/contactsearch.php delete mode 100644 crumb/docs/CHANGES delete mode 100644 crumb/docs/CREDITS delete mode 100644 crumb/docs/INSTALL delete mode 100644 crumb/docs/RELEASE_NOTES delete mode 100644 crumb/docs/TODO delete mode 100644 crumb/index.php delete mode 100644 crumb/lib/Application.php delete mode 100644 crumb/lib/Block/example.php delete mode 100644 crumb/lib/Crumb.php delete mode 100644 crumb/lib/Driver.php delete mode 100644 crumb/lib/Driver/sql.php delete mode 100644 crumb/lib/Forms/AddClient.php delete mode 100644 crumb/lib/Forms/ContactSearch.php delete mode 100644 crumb/lib/base.php delete mode 100644 crumb/listclients.php delete mode 100644 crumb/locale delete mode 100644 crumb/scripts/sql/crumb.sql delete mode 100644 crumb/templates/common-header.inc delete mode 100644 crumb/templates/menu.inc delete mode 100644 crumb/themes/screen.css delete mode 100644 drag_n_drop_portal/block.php delete mode 100644 drag_n_drop_portal/index.php delete mode 100644 drag_n_drop_portal/js/portal.js delete mode 100644 drag_n_drop_portal/js/portal_edit.js delete mode 100644 drag_n_drop_portal/lib/Block/Layout/View/js.php delete mode 100644 drag_n_drop_portal/params.php delete mode 100644 drag_n_drop_portal/save.php delete mode 100644 drag_n_drop_portal/select.php delete mode 100644 drag_n_drop_portal/templates/portal/params.php delete mode 100644 drag_n_drop_portal/themes/graphics/bottom_left.gif delete mode 100644 drag_n_drop_portal/themes/graphics/bottom_right.gif delete mode 100644 drag_n_drop_portal/themes/graphics/delete.png delete mode 100644 drag_n_drop_portal/themes/graphics/edit.png delete mode 100644 drag_n_drop_portal/themes/graphics/minus.png delete mode 100644 drag_n_drop_portal/themes/graphics/plus.png delete mode 100644 drag_n_drop_portal/themes/graphics/reload.png delete mode 100644 drag_n_drop_portal/themes/graphics/tooltip_bg.png delete mode 100644 drag_n_drop_portal/themes/graphics/top_left.gif delete mode 100644 drag_n_drop_portal/themes/graphics/top_right.gif delete mode 100644 drag_n_drop_portal/themes/screen.css delete mode 100644 fima/COPYING delete mode 100644 fima/README delete mode 100644 fima/account.php delete mode 100644 fima/accounts.php delete mode 100644 fima/config/.htaccess delete mode 100644 fima/config/conf.xml delete mode 100644 fima/config/menu.php.dist delete mode 100644 fima/config/prefs.php.dist delete mode 100644 fima/config/report.php.dist delete mode 100644 fima/data.php delete mode 100644 fima/docs/CHANGES delete mode 100644 fima/docs/CREDITS delete mode 100644 fima/docs/INSTALL delete mode 100644 fima/docs/RELEASE_NOTES delete mode 100644 fima/docs/TODO delete mode 100644 fima/index.php delete mode 100644 fima/ledgers/create.php delete mode 100644 fima/ledgers/delete.php delete mode 100644 fima/ledgers/edit.php delete mode 100644 fima/ledgers/index.php delete mode 100644 fima/lib/Application.php delete mode 100644 fima/lib/Block/summary.php delete mode 100644 fima/lib/Block/tree_menu.php delete mode 100644 fima/lib/Driver.php delete mode 100644 fima/lib/Driver/sql.php delete mode 100644 fima/lib/Fima.php delete mode 100644 fima/lib/Forms/CreateLedger.php delete mode 100644 fima/lib/Forms/DeleteLedger.php delete mode 100644 fima/lib/Forms/EditLedger.php delete mode 100644 fima/lib/Forms/account.php delete mode 100644 fima/lib/Report.php delete mode 100644 fima/lib/Report/AccountOverview.php delete mode 100644 fima/lib/Report/Analysis.php delete mode 100644 fima/lib/Report/AssetOverview.php delete mode 100644 fima/lib/Report/GeneralOverview.php delete mode 100644 fima/lib/Report/PeriodOverview.php delete mode 100644 fima/lib/Report/Trend.php delete mode 100644 fima/lib/ReportGraph.php delete mode 100644 fima/lib/ReportGraph/Bar.php delete mode 100644 fima/lib/ReportGraph/Line.php delete mode 100644 fima/lib/ReportGraph/Pie.php delete mode 100644 fima/lib/UI/VarRenderer/fima.php delete mode 100644 fima/lib/base.php delete mode 100644 fima/locale/.htaccess delete mode 100644 fima/locale/de/LC_MESSAGES/fima.mo delete mode 100644 fima/locale/de/LC_MESSAGES/fima.po delete mode 100644 fima/locale/de/help.xml delete mode 100644 fima/locale/en/help.xml delete mode 100644 fima/locale/fima.pot delete mode 100644 fima/postings.php delete mode 100644 fima/report.php delete mode 100644 fima/scripts/sql/fima.sql delete mode 100644 fima/search.php delete mode 100644 fima/templates/accounts/accounts.inc delete mode 100644 fima/templates/common-header.inc delete mode 100644 fima/templates/data/export.inc delete mode 100644 fima/templates/data/import.inc delete mode 100644 fima/templates/ledgers_list.php delete mode 100644 fima/templates/menu.inc delete mode 100644 fima/templates/postings/actions.inc delete mode 100644 fima/templates/postings/edit.inc delete mode 100644 fima/templates/postings/empty.inc delete mode 100644 fima/templates/postings/footer.inc delete mode 100644 fima/templates/postings/header.inc delete mode 100644 fima/templates/postings/javascript_edit.inc delete mode 100644 fima/templates/postings/javascript_list.inc delete mode 100644 fima/templates/postings/javascript_shift.inc delete mode 100644 fima/templates/postings/javascript_transfer.inc delete mode 100644 fima/templates/postings/list.inc delete mode 100644 fima/templates/postings/navbar.inc delete mode 100644 fima/templates/postings/posting_footers.inc delete mode 100644 fima/templates/postings/posting_headers.inc delete mode 100644 fima/templates/postings/shift.inc delete mode 100644 fima/templates/postings/transfer.inc delete mode 100644 fima/templates/reports/empty.inc delete mode 100644 fima/templates/reports/graph.inc delete mode 100644 fima/templates/reports/img.inc delete mode 100644 fima/templates/reports/reports.inc delete mode 100644 fima/templates/reports/table.inc delete mode 100644 fima/templates/search/search.inc delete mode 100644 fima/themes/bluewhite/screen.css delete mode 100644 fima/themes/graphics/accounts.png delete mode 100644 fima/themes/graphics/accounts.psd delete mode 100644 fima/themes/graphics/add.png delete mode 100644 fima/themes/graphics/asset.png delete mode 100644 fima/themes/graphics/eoasset.png delete mode 100644 fima/themes/graphics/eoexpense.png delete mode 100644 fima/themes/graphics/eoincome.png delete mode 100644 fima/themes/graphics/expense.png delete mode 100644 fima/themes/graphics/fima.png delete mode 100644 fima/themes/graphics/income.png delete mode 100644 fima/themes/graphics/list.png delete mode 100644 fima/themes/graphics/new-small.png delete mode 100644 fima/themes/graphics/posting.psd delete mode 100644 fima/themes/graphics/report.png delete mode 100644 fima/themes/graphics/reports.psd delete mode 100644 fima/themes/graphics/search-small.png delete mode 100644 fima/themes/report.inc delete mode 100644 fima/themes/screen.css delete mode 100644 fima/themes/silver/graphics/accounts.png delete mode 100644 fima/themes/silver/graphics/accounts.psd delete mode 100644 fima/themes/silver/graphics/add.png delete mode 100644 fima/themes/silver/graphics/asset.png delete mode 100644 fima/themes/silver/graphics/eoasset.png delete mode 100644 fima/themes/silver/graphics/eoexpense.png delete mode 100644 fima/themes/silver/graphics/eoincome.png delete mode 100644 fima/themes/silver/graphics/expense.png delete mode 100644 fima/themes/silver/graphics/fima.png delete mode 100644 fima/themes/silver/graphics/income.png delete mode 100644 fima/themes/silver/graphics/list.png delete mode 100644 fima/themes/silver/graphics/new-small.png delete mode 100644 fima/themes/silver/graphics/posting.psd delete mode 100644 fima/themes/silver/graphics/report.png delete mode 100644 fima/themes/silver/graphics/report.psd delete mode 100644 fima/themes/silver/graphics/search-small.png delete mode 100644 fima/themes/silver/screen.css delete mode 100644 flexdemo/alt.php delete mode 100644 flexdemo/garland/app.html.php delete mode 100644 flexdemo/garland/css/defaults-rtl.css delete mode 100644 flexdemo/garland/css/defaults.css delete mode 100644 flexdemo/garland/css/fix-ie-rtl.css delete mode 100644 flexdemo/garland/css/fix-ie.css delete mode 100644 flexdemo/garland/css/print.css delete mode 100644 flexdemo/garland/css/style-rtl.css delete mode 100644 flexdemo/garland/css/style.css delete mode 100644 flexdemo/garland/images/bg-bar-white.png delete mode 100644 flexdemo/garland/images/bg-bar.png delete mode 100644 flexdemo/garland/images/bg-content-left.png delete mode 100644 flexdemo/garland/images/bg-content-right.png delete mode 100644 flexdemo/garland/images/bg-content.png delete mode 100644 flexdemo/garland/images/bg-navigation-item-hover.png delete mode 100644 flexdemo/garland/images/bg-navigation-item.png delete mode 100644 flexdemo/garland/images/bg-navigation.png delete mode 100644 flexdemo/garland/images/bg-tab.png delete mode 100644 flexdemo/garland/images/body.png delete mode 100644 flexdemo/garland/images/gradient-inner.png delete mode 100644 flexdemo/garland/images/menu-collapsed-rtl.gif delete mode 100644 flexdemo/garland/images/menu-collapsed.gif delete mode 100644 flexdemo/garland/images/menu-expanded.gif delete mode 100644 flexdemo/garland/images/menu-leaf.gif delete mode 100644 flexdemo/garland/images/task-list.png delete mode 100644 flexdemo/garland/left.html.php delete mode 100644 flexdemo/garland/list.html.php delete mode 100644 flexdemo/garland/main.html.php delete mode 100644 flexdemo/garland/right.html.php delete mode 100644 flexdemo/garland/secondary.html.php delete mode 100644 flexdemo/index.php delete mode 100644 flexdemo/lib/Block/block1.php delete mode 100644 flexdemo/lib/Block/block2.php delete mode 100644 flexdemo/lib/Block/menu.php delete mode 100644 jeta/COPYING delete mode 100644 jeta/README delete mode 100644 jeta/config/.htaccess delete mode 100644 jeta/config/conf.xml delete mode 100644 jeta/config/prefs.php.dist delete mode 100644 jeta/docs/CHANGES delete mode 100644 jeta/docs/CREDITS delete mode 100644 jeta/docs/INSTALL delete mode 100644 jeta/docs/RELEASE_NOTES delete mode 100644 jeta/index.php delete mode 100644 jeta/jar/SSHTermApplet-jdk1.3.1-dependencies-signed.jar delete mode 100644 jeta/jar/SSHTermApplet-jdkbug-workaround-signed.jar delete mode 100644 jeta/jar/SSHTermApplet-signed.jar delete mode 100644 jeta/jar/jta.conf delete mode 100755 jeta/jar/jta26.jar delete mode 100644 jeta/lib/.htaccess delete mode 100644 jeta/lib/Applet.php delete mode 100644 jeta/lib/Applet/jta.php delete mode 100644 jeta/lib/Applet/sshtools.php delete mode 100644 jeta/lib/Application.php delete mode 100644 jeta/lib/Test.php delete mode 100644 jeta/locale/.htaccess delete mode 100644 jeta/locale/cs/LC_MESSAGES/jeta.mo delete mode 100644 jeta/locale/cs/LC_MESSAGES/jeta.po delete mode 100644 jeta/locale/de/LC_MESSAGES/jeta.mo delete mode 100644 jeta/locale/de/LC_MESSAGES/jeta.po delete mode 100644 jeta/locale/de/help.xml delete mode 100644 jeta/locale/en/help.xml delete mode 100644 jeta/locale/es/LC_MESSAGES/jeta.mo delete mode 100644 jeta/locale/es/LC_MESSAGES/jeta.po delete mode 100644 jeta/locale/es/help.xml delete mode 100644 jeta/locale/fi/LC_MESSAGES/jeta.mo delete mode 100644 jeta/locale/fi/LC_MESSAGES/jeta.po delete mode 100644 jeta/locale/jeta.pot delete mode 100644 jeta/locale/ro/LC_MESSAGES/jeta.mo delete mode 100644 jeta/locale/ro/LC_MESSAGES/jeta.po delete mode 100644 jeta/locale/zh_TW/LC_MESSAGES/jeta.mo delete mode 100644 jeta/locale/zh_TW/LC_MESSAGES/jeta.po delete mode 100644 jeta/templates/common-header.inc delete mode 100644 jeta/templates/main.html delete mode 100644 jeta/themes/graphics/favicon.ico delete mode 100644 jeta/themes/graphics/jeta.png delete mode 100644 kastalia/COPYING delete mode 100644 kastalia/LICENSE.ASL delete mode 100755 kastalia/LICENSE.BSDL delete mode 100644 kastalia/README delete mode 100644 kastalia/config/.htaccess delete mode 100644 kastalia/config/conf.php delete mode 100644 kastalia/config/conf.xml delete mode 100644 kastalia/datastore/.htaccess delete mode 100644 kastalia/decrypt_menu.php delete mode 100644 kastalia/docs/CHANGES delete mode 100644 kastalia/docs/CREDITS delete mode 100644 kastalia/docs/INSTALL delete mode 100755 kastalia/docs/RELEASE_NOTES delete mode 100644 kastalia/docs/TODO delete mode 100755 kastalia/download.php delete mode 100644 kastalia/encrypt_decrypt_files.php delete mode 100755 kastalia/index.php delete mode 100644 kastalia/lib/Application.php delete mode 100644 kastalia/lib/Block/tree_menu.php delete mode 100644 kastalia/lib/Kastalia.php delete mode 100644 kastalia/lib/base.php delete mode 100755 kastalia/list.php delete mode 100644 kastalia/locale/.htaccess delete mode 100644 kastalia/locale/de/help.xml delete mode 100755 kastalia/locale/en/help.xml delete mode 100644 kastalia/locale/kastalia.pot delete mode 100755 kastalia/main.php delete mode 100644 kastalia/temp/.htaccess delete mode 100644 kastalia/templates/common-footer.inc delete mode 100755 kastalia/templates/common-header.inc delete mode 100755 kastalia/templates/menu.inc delete mode 100755 kastalia/themes/graphics/directory_closed.gif delete mode 100644 kastalia/themes/graphics/directory_open.gif delete mode 100644 kastalia/themes/graphics/file.gif delete mode 100644 kastalia/themes/graphics/file_enc.gif delete mode 100644 kastalia/themes/graphics/kastalia.png delete mode 100644 kastalia/themes/graphics/loader.gif delete mode 100644 kastalia/themes/graphics/menu/upload.png delete mode 100755 kastalia/themes/screen.css delete mode 100644 kastalia/upload.php delete mode 100644 kastalia/upload_menu.php delete mode 100644 news/add.php delete mode 100644 news/admin/categories/delete.php delete mode 100644 news/admin/categories/edit.php delete mode 100644 news/admin/categories/index.php delete mode 100644 news/admin/sources/delete.php delete mode 100644 news/admin/sources/edit.php delete mode 100644 news/admin/sources/index.php delete mode 100644 news/admin/tabs.php delete mode 100644 news/browse.php delete mode 100644 news/cloud.php delete mode 100644 news/config/conf.xml delete mode 100644 news/config/prefs.php.dist delete mode 100644 news/content.php delete mode 100644 news/content_edit.php delete mode 100644 news/delete.php delete mode 100644 news/delete_file.php delete mode 100644 news/diff.php delete mode 100644 news/edit.php delete mode 100644 news/feed.php delete mode 100644 news/files.php delete mode 100644 news/index.php delete mode 100644 news/js/feed.js delete mode 100644 news/lib/Api.php delete mode 100644 news/lib/Application.php delete mode 100755 news/lib/Block/categories.php delete mode 100755 news/lib/Block/category.php delete mode 100755 news/lib/Block/jonah.php delete mode 100755 news/lib/Block/last.php delete mode 100755 news/lib/Block/last_blogs.php delete mode 100755 news/lib/Block/last_comments.php delete mode 100755 news/lib/Block/most_commented.php delete mode 100755 news/lib/Block/most_read.php delete mode 100644 news/lib/Block/my_comments.php delete mode 100755 news/lib/Block/sources.php delete mode 100644 news/lib/Block/tags_cloud.php delete mode 100644 news/lib/Categories.php delete mode 100644 news/lib/Driver.php delete mode 100644 news/lib/Driver/sql.php delete mode 100644 news/lib/Forms/Search.php delete mode 100644 news/lib/News.php delete mode 100644 news/lib/Search.php delete mode 100644 news/lib/TagCloud.php delete mode 100644 news/lib/View.php delete mode 100644 news/lib/base.php delete mode 100644 news/locale/.htaccess delete mode 100644 news/locale/news.pot delete mode 100755 news/locale/sl/LC_MESSAGES/news.mo delete mode 100644 news/locale/sl/LC_MESSAGES/news.po delete mode 100644 news/mail.php delete mode 100644 news/news.php delete mode 100644 news/note.php delete mode 100644 news/pdf.php delete mode 100644 news/po/messages.mo delete mode 100644 news/print.php delete mode 100644 news/reads.php delete mode 100644 news/rss/comments.php delete mode 100644 news/rss/index.php delete mode 100755 news/rss/news.php delete mode 100644 news/scripts/sql/news.mysql.sql delete mode 100644 news/scripts/upgrades/20070302_trackback.sql delete mode 100644 news/scripts/upgrades/20070609_sponsored.sql delete mode 100644 news/scripts/upgrades/20071220_tags.sql delete mode 100644 news/search.php delete mode 100644 news/tags.php delete mode 100755 news/templates/add/before.inc delete mode 100644 news/templates/block/news.php delete mode 100644 news/templates/block/titles.php delete mode 100755 news/templates/browse/footer.inc delete mode 100755 news/templates/browse/header.inc delete mode 100755 news/templates/browse/row.inc delete mode 100755 news/templates/categories/delete.html delete mode 100755 news/templates/categories/edit.html delete mode 100755 news/templates/categories/index.html delete mode 100644 news/templates/categories/index.php delete mode 100644 news/templates/common-header.inc delete mode 100755 news/templates/edit/footer.inc delete mode 100755 news/templates/edit/header.inc delete mode 100644 news/templates/edit/info.php delete mode 100644 news/templates/edit/row.php delete mode 100644 news/templates/menu.inc delete mode 100644 news/templates/news/attachments.php delete mode 100644 news/templates/news/blog.php delete mode 100644 news/templates/news/comments.php delete mode 100644 news/templates/news/gallery.php delete mode 100644 news/templates/news/info.php delete mode 100644 news/templates/news/mail.php delete mode 100644 news/templates/news/news.php delete mode 100644 news/templates/news/parents.php delete mode 100644 news/templates/news/selling.php delete mode 100644 news/templates/news/threads.php delete mode 100644 news/templates/news/today.php delete mode 100644 news/templates/news/tools.php delete mode 100644 news/templates/news/ulaform.php delete mode 100755 news/templates/print/footer.inc delete mode 100755 news/templates/print/header.inc delete mode 100755 news/templates/reads/footer.inc delete mode 100755 news/templates/reads/header.inc delete mode 100755 news/templates/reads/row.inc delete mode 100644 news/templates/sources/index.php delete mode 100644 news/themes/graphics/folder_open.png delete mode 100644 news/themes/graphics/mkdir.png delete mode 100644 news/themes/graphics/news.png delete mode 100755 news/themes/screen.css delete mode 100644 news/trackback.php delete mode 100644 skoli/LICENSE delete mode 100644 skoli/README delete mode 100644 skoli/add.php delete mode 100644 skoli/classes/create.php delete mode 100644 skoli/classes/delete.php delete mode 100644 skoli/classes/edit.php delete mode 100644 skoli/classes/index.php delete mode 100644 skoli/config/conf.xml delete mode 100644 skoli/config/prefs.php.dist delete mode 100644 skoli/config/schools.php.dist delete mode 100644 skoli/data.php delete mode 100644 skoli/docs/CHANGES delete mode 100644 skoli/docs/CREDITS delete mode 100644 skoli/docs/INSTALL delete mode 100644 skoli/docs/RELEASE_NOTES delete mode 100644 skoli/docs/TODO delete mode 100644 skoli/entry.php delete mode 100644 skoli/index.php delete mode 100644 skoli/lib/Ajax/Application.php delete mode 100644 skoli/lib/Application.php delete mode 100644 skoli/lib/Block/tree_menu.php delete mode 100644 skoli/lib/Driver.php delete mode 100644 skoli/lib/Driver/sql.php delete mode 100644 skoli/lib/Forms/CreateClass.php delete mode 100644 skoli/lib/Forms/DeleteClass.php delete mode 100644 skoli/lib/Forms/EditClass.php delete mode 100644 skoli/lib/Forms/Entry.php delete mode 100644 skoli/lib/School.php delete mode 100644 skoli/lib/Skoli.php delete mode 100644 skoli/lib/base.php delete mode 100644 skoli/list.php delete mode 100644 skoli/locale/.htaccess delete mode 100644 skoli/locale/de/LC_MESSAGES/skoli.mo delete mode 100644 skoli/locale/de/LC_MESSAGES/skoli.po delete mode 100644 skoli/locale/de/help.xml delete mode 100644 skoli/locale/en/help.xml delete mode 100644 skoli/locale/skoli.pot delete mode 100755 skoli/scripts/.htaccess delete mode 100755 skoli/scripts/sql/skoli.sql delete mode 100644 skoli/search.php delete mode 100644 skoli/templates/classes/list.php delete mode 100644 skoli/templates/common-header.inc delete mode 100644 skoli/templates/data/export.inc delete mode 100644 skoli/templates/entry/delete.inc delete mode 100644 skoli/templates/list/classes.inc delete mode 100644 skoli/templates/list/empty.inc delete mode 100644 skoli/templates/list/footers.inc delete mode 100644 skoli/templates/list/header.inc delete mode 100644 skoli/templates/list/headers.inc delete mode 100644 skoli/templates/list/students.inc delete mode 100644 skoli/templates/menu.inc delete mode 100644 skoli/templates/panel.inc delete mode 100644 skoli/templates/search/criteria.inc delete mode 100644 skoli/templates/search/empty.inc delete mode 100644 skoli/templates/search/entries.inc delete mode 100644 skoli/templates/search/footers.inc delete mode 100644 skoli/templates/search/header.inc delete mode 100644 skoli/templates/search/headers.inc delete mode 100644 skoli/themes/categoryCSS.php delete mode 100644 skoli/themes/graphics/add.png delete mode 100644 skoli/themes/graphics/az.png delete mode 100644 skoli/themes/graphics/favicon.ico delete mode 100644 skoli/themes/graphics/minus.png delete mode 100644 skoli/themes/graphics/plus.png delete mode 100644 skoli/themes/graphics/search.png delete mode 100644 skoli/themes/graphics/skoli.png delete mode 100644 skoli/themes/graphics/timetable.png delete mode 100644 skoli/themes/graphics/za.png delete mode 100644 skoli/themes/screen.css diff --git a/babel/COPYING b/babel/COPYING deleted file mode 100644 index a6b67561a..000000000 --- a/babel/COPYING +++ /dev/null @@ -1,280 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright 1989, 1991 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -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 Program or any portion -of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -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 Program, 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 Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) 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; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, 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 executable. However, as a -special exception, the source code 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. - -If distribution of executable or 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 counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. 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 Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program 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 to -this License. - - 7. 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 Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program 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 Program. - -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. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program 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. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 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 Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, 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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. 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 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. - - END OF TERMS AND CONDITIONS diff --git a/babel/README b/babel/README deleted file mode 100644 index e05f7f649..000000000 --- a/babel/README +++ /dev/null @@ -1,86 +0,0 @@ -What is Babel? -============== - -:Contact: joel@scopserv.com - -.. contents:: Contents -.. section-numbering:: - -Babel is a web interface to viewing and editing PO (gettext) files for all -modules written in PHP and utilizing the `Horde Application Framework`_. - -This software is OSI Certified Open Source Software. OSI Certified is a -certification mark of the `Open Source Initiative`_. - -.. _`Horde Application Framework`: http://www.horde.org/horde/ -.. _`Open Source Initiative`: http://www.opensource.org/ - - -Obtaining Babel ---------------- - -Further information on Babel and the latest version can be obtained at - - http://.../ - - -Documentation -------------- - -The following documentation is available in the Babel distribution: - -:README_: This file -:COPYING_: Copyright and license information -:`docs/BUGS`_: Known bugs -:`docs/CHANGES`_: Changes by release -:`docs/CREDITS`_: Project developers -:`docs/INSTALL`_: Installation instructions and notes -:`docs/TODO`_: Development TODO list - - -Installation ------------- - -Instructions for installing Babel can be found in the file INSTALL_ in the -``docs/`` directory of the Babel distribution. - - -Assistance ----------- - -If you encounter problems with Babel, help is available! - -The Horde Frequently Asked Questions List (FAQ), available on the Web at - - http://www.horde.org/faq/ - -The Horde Project runs a number of mailing lists, for individual applications -and for issues relating to the project as a whole. Information, archives, and -subscription information can be found at - - http://www.horde.org/mail/ - -Lastly, Horde developers, contributors and users also make occasional -appearances on IRC, on the channel #horde on the freenode Network -(irc.freenode.net). - - -Licensing ---------- - -For licensing and copyright information, please see the file COPYING_ in the -Babel distribution. - -Thanks, - -The Babel team - - -.. _README: ?f=README.html -.. _COPYING: http://www.horde.org/licenses/gpl.php -.. _docs/BUGS: ?f=BUGS.html -.. _docs/CHANGES: ?f=CHANGES.html -.. _docs/CREDITS: ?f=CREDITS.html -.. _INSTALL: -.. _docs/INSTALL: ?f=INSTALL.html -.. _docs/TODO: ?f=TODO.html diff --git a/babel/commit.php b/babel/commit.php deleted file mode 100644 index 05879697d..000000000 --- a/babel/commit.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @package Babel - */ - -@define('BABEL_BASE', dirname(__FILE__)) ; -require_once BABEL_BASE . '/lib/base.php'; - -// Define if we use Horde CVS or Custom Commit -$custom_commit = true; - -/* Render the page. */ -require BABEL_TEMPLATES . '/common-header.inc'; -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -Translate_Display::header(_("Horde translation generator")); - -/* Do sanity check */ -Translate::sanity_check(); - -/* Searching applications */ -Translate::check_binaries(); - -Translate_Display::info(sprintf('Searching Horde applications in %s', realpath(HORDE_BASE))); -$dirs = Translate::search_applications(); - -$apps = Translate::strip_horde($dirs); -$apps[0] = 'horde'; -Translate_Display::info(_("Found applications:")); -Translate_Display::info(wordwrap(implode(', ', $apps)), false); -Translate_Display::info(); - -// Check if we must execute Custom commit or Horde CVS Commit (Developer) -if ($custom_commit) { - Translate_Display::header(_("Commit PO files ...")); - foreach($dirs as $d => $dir) { - $dir = realpath($dir); - $po = $dir . '/po/' . $lang . '.po'; - - if (@file_exists($po)) { - Translate_Display::info(_("Commit") . " $po ($lang)"); - Babel::callHook('commit', array($po, $lang)); - } - - } -} else { - Translate::commit(); -} - - -Translate_Display::info(); - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/config/hooks.php.dist b/babel/config/hooks.php.dist deleted file mode 100644 index f67eae5be..000000000 --- a/babel/config/hooks.php.dist +++ /dev/null @@ -1,28 +0,0 @@ - - -Thanks to Michael Wallner for File_Gettext PEAR library. - - -Localization -============ - -===================== ====================================================== -French Joel Vandal -===================== ====================================================== diff --git a/babel/docs/TODO b/babel/docs/TODO deleted file mode 100644 index 44a17420c..000000000 --- a/babel/docs/TODO +++ /dev/null @@ -1,8 +0,0 @@ -============================= - Babel Development TODO List -============================= - -:Contact: joel@scopsev.com - -- Add support for Obsolete strings. - diff --git a/babel/download.php b/babel/download.php deleted file mode 100644 index 8a3a2e3b0..000000000 --- a/babel/download.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @package Babel - */ - -$no_compress = true; - -$title = _("Download File"); - -@define('BABEL_BASE', dirname(__FILE__)); -require_once BABEL_BASE . '/lib/base.php'; - -$files = array(); -$dirs = Translate::search_applications(); -foreach($dirs as $d => $dir) { - $dir = realpath($dir); - - $app = str_replace(realpath(HORDE_BASE), '', $dir); - $app = str_replace('/', '', $app); - if (empty($app)) { - $app = 'horde'; - } - - $po = $dir . '/po/' . $lang . '.po'; - if (@file_exists($po)) { - $files[$app] = $po; - } -} - -$filename = "po-" . $lang . ".zip"; -@system("rm -rf /tmp/$filename"); -@system("rm -rf /tmp/translate"); -@mkdir("/tmp/translate"); -foreach($files as $app => $file) { - $cmd = "cp $file /tmp/translate/$app-" . basename($file); - @system($cmd); -} -$cmd = "zip -j /tmp/$filename /tmp/translate/*"; -@exec($cmd); - -$data = file_get_contents("/tmp/$filename"); - -$browser->downloadHeaders($filename); -echo $data; diff --git a/babel/edit.php b/babel/edit.php deleted file mode 100644 index 83a4df105..000000000 --- a/babel/edit.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @package Babel - */ - -$meta_params = array( - "Project-Id-Version" => @$_SESSION['babel']['language'], - "Report-Msgid-Bugs-To" => "support@scopserv.com", - "POT-Creation-Date" => "", - "PO-Revision-Date" => "", - "Last-Translator" => "", - "Language-Team" => "", - "MIME-Version" => "1.0", - "Content-Type" => "text/plain; charset=utf-8", - "Content-Transfer-Encoding" => "8bit", - "Plural-Forms" => "nplurals=2; plural=(n > 1);"); - - -require_once dirname(__FILE__) . '/lib/base.php'; -require_once BABEL_BASE . '/lib/Gettext/PO.php'; - -require_once 'Horde/Form.php'; -require_once 'Horde/Form/Renderer.php'; -require_once 'Horde/Form/Action.php'; - -$app = Horde_Util::getFormData('module'); - -$show = 'edit'; -$vars = &Horde_Variables::getDefaultVariables(); - -if ($app) { - $napp = ($app == 'horde') ? '' : $app; - $pofile = HORDE_BASE . '/' . $napp . '/po/' . $_SESSION['babel']['language'] . '.po'; - $po = new File_Gettext_PO(); - $po->load($pofile); -} - -/* Set up the template fields. */ -$template->set('menu', Babel::getMenu()->render()); - -Horde::startBuffer(); -$notification->notify(array('listeners' => 'status'))); -$template->set('notify', Horde::endBuffer()); - -/* Create upload form */ -$form = new Horde_Form($vars, _("Edit Translation"), $show); - -/* Validate form if submitted */ -if ($app && Horde_Util::getFormData('submitbutton') == _("Save")) { - - if ($form->validate($vars, false)) { - $form->getInfo($vars, $form_values); - - foreach($meta_params as $k => $v) { - if ($val = Horde_Util::getFormData($k)) { - $po->meta[$k] = $val; - } - } - - $po->save($pofile); - - if (Horde_Util::getFormData('url') == 'view') { - Horde::url('view.php')->add('module' => $app)->redirect(); - } - } -} - -if (!$app) { - $form->setButtons(_("Edit")); - $form->addVariable(_("Module"), 'module', 'enum', true, false, null, array(Babel::listApps(), true)); - $form->addVariable('', '', 'spacer', true); -} else { - - $form->setButtons(_("Save")); - $form->addHidden('', 'module', 'text', false); - $vars->set('module', $app); - - $form->addHidden('', 'url', 'text', false); - $vars->set('url', Horde_Util::getFormData('url')); - - foreach($meta_params as $k => $v) { - $form->addVariable($k, $k, 'text', false, false); - if (isset($po->meta[$k]) && !empty($po->meta[$k])) { - $vars->set($k, $po->meta[$k]); - } elseif (!empty($v)) { - $vars->set($k, $v); - } - } -} - -/* Render the page. */ -require BABEL_TEMPLATES . '/common-header.inc'; - -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -$renderer_params = array(); -$renderer = new Horde_Form_Renderer($renderer_params); -$renderer->setAttrColumnWidth('20%'); - -$form->renderActive($renderer, $vars, Horde::selfURL(), 'post'); - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/extract.php b/babel/extract.php deleted file mode 100644 index 3c3f91995..000000000 --- a/babel/extract.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @package Babel - */ - -set_time_limit(0); - -@define('BABEL_BASE', dirname(__FILE__)) ; -require_once BABEL_BASE . '/lib/base.php'; - -if ($app) { - Babel::RB_init(); -} - -/* Render the page. */ -require BABEL_TEMPLATES . '/common-header.inc'; - -if ($app) { - Babel::RB_start(300); -} - -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -$vars = &Horde_Variables::getDefaultVariables(); - -/* Create upload form */ -$form = new Horde_Form($vars, _("Extract Translation"), 'extract'); - -if (!$app) { - $form->setButtons(_("Extract")); - $form->addVariable(_("Module"), 'module', 'enum', true, false, null, array(Babel::listApps(true), true)); - $form->addVariable('', '', 'spacer', true); - - $renderer_params = array(); - $renderer = new Horde_Form_Renderer($renderer_params); - $renderer->setAttrColumnWidth('20%'); - - $form->renderActive($renderer, $vars, Horde::selfURL(), 'post'); -} else { - Translate_Display::header(_("Horde translation generator")); - - /* Sanity checks */ - if (!extension_loaded('gettext')) { - Translate_Display::error(_("Gettext extension not found!")); - footer(); - } - - Translate_Display::info(_("Loading libraries...")); - $libs_found = true; - - foreach (array('Console_Getopt' => 'Console/Getopt.php', - 'Console_Table' => 'Console/Table.php', - 'File_Find' => 'File/Find.php') - as $class => $file) { - @include_once $file; - if (class_exists($class)) { - // Translate_Display::info("$class ...", false); - } else { - Translate_Display::error(sprintf(_("%s not found."), $class)); - $libs_found = false; - } - } - - if (!$libs_found) { - Translate_Display::info(); - Translate_Display::info(_("Make sure that you have PEAR installed and in your include path.")); - Translate_Display::info('include_path: ' . ini_get('include_path')); - } - Translate_Display::info(); - - /* Searching applications */ - Translate::check_binaries(); - - Translate_Display::info(sprintf(_("Searching Horde applications in %s"), realpath(HORDE_BASE))); - $dirs = Translate::search_applications(); - - if ($app == 'ALL') { - Translate_Display::info(_("Found directories:"), false); - Translate_Display::info(implode("\n", $dirs), false); - } - Translate_Display::info(); - - $apps = Translate::strip_horde($dirs); - $apps[0] = 'horde'; - if ($app == 'ALL') { - Translate_Display::info(_("Found applications:")); - Translate_Display::info(wordwrap(implode(', ', $apps)), false); - Translate_Display::info(); - } - - global $module; - if ($app != 'ALL') { - $module = $app; - } - - Translate::init(); - Translate::cleanup(); - - Translate_Display::header(_("Generate Compendium ...")); - Translate::compendium(); - Translate_Display::info(); - - Translate::xtract(); - Translate_Display::info(); - Translate::merge(); - - Translate_Display::info(); - Translate_Display::header(_("Done!")); - - Babel::RB_close(); -} - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/index.php b/babel/index.php deleted file mode 100644 index a6d12cd52..000000000 --- a/babel/index.php +++ /dev/null @@ -1,21 +0,0 @@ - - * @package Babel - */ - -@define('BABEL_BASE', dirname(__FILE__)) ; -require_once BABEL_BASE . '/lib/base.php'; - -/* Render the page. */ -require BABEL_TEMPLATES . '/common-header.inc'; -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -require BABEL_TEMPLATES . '/index.php'; - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/lib/Application.php b/babel/lib/Application.php deleted file mode 100644 index 9b4289515..000000000 --- a/babel/lib/Application.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package Babel - */ -class Babel_Application extends Horde_Registry_Application -{ - public $version = 'H4 (0.1-git)'; - - /** - * Returns a list of available permissions. - * - * @return array An array describing all available permissions. - */ - public function perms() - { - global $registry; - - $perms = array( - 'language' => array( - 'title' => _("Languages"), - 'type' => 'none' - ), - 'module' => array( - 'title' => _("Modules"), - 'type' => 'none' - ) - ); - - foreach($registry->nlsconfig['languages'] as $langcode => $langdesc) { - $perms['language:' . $langcode] = array( - 'title' => sprintf("%s (%s)", $langdesc, $langcode), - 'type' => 'boolean' - ); - } - - - foreach ($registry->applications as $app => $params) { - if (in_array($params['status'], array('block', 'heading')) || - (isset($params['fileroot']) && !is_dir($params['fileroot'])) || - preg_match('/_[tools|reports]$/', $app)) { - continue; - } - - $perms['module:' . $app] = array( - 'title' => sprintf("%s (%s)", $params['name'], $app), - 'type' => 'boolean' - ); - } - - $tabdesc = array( - 'download' => _("Download"), - 'upload' => _("Upload"), - 'stats' => _("Statistics"), - 'view' => _("View/Edit"), - 'viewsource' => _("View Source"), - 'extract' => _("Extract"), - 'make' => _("Make"), - 'commit' => _("Commit"), - 'reset' => _("Reset") - ); - - foreach ($tabdesc as $cat => $desc) { - $perms[$cat] = array( - 'title' => $desc - ); - } - - return $perms; - } - -} diff --git a/babel/lib/Babel.php b/babel/lib/Babel.php deleted file mode 100644 index a906131aa..000000000 --- a/babel/lib/Babel.php +++ /dev/null @@ -1,304 +0,0 @@ - - * @package Babel - */ - -class Babel { - - function callHook($fname, $info) { - /* Check if an hooks file exist */ - if (file_exists(BABEL_BASE . '/config/hooks.php')) { - include_once BABEL_BASE . '/config/hooks.php'; - - $func = '_babel_hook_' . $fname; - - if (function_exists($func)) { - $res = call_user_func($func, $info); - } else { - Translate_Display::warning(sprintf(_("Function doesn't exist: %s"), $func)); - } - } else { - Translate_Display::warning(_("Hook file doesn't exist")); - } - } - - function displayLanguage() { - global $lang, $app; - - if (!isset(Horde_Nls::$config['languages'][$lang])) { - return; - } - - $res = sprintf(_("Language: %s (%s)"), Horde_Nls::$config['languages'][$lang], $lang); - if ($app) { - $res .= '  |   ' . sprintf(_("Module: %s"), $app); - } - - return $res; - } - - - function ModuleSelection() { - $html = ''; - $html .= ''; - $html .= '
'; - $html .= ''; - $html .= '
'; - $html .= '
'; - - $html .= '' . "\n"; - return $html; - } - - function LanguageSelection() { - global $app; - - $html = ''; - $html .= ''; - $html .= '
'; - $html .= ' '; - $html .= ''; - $html .= ''; - $html .= ' '; - $html .= '
'; - $html .= '
'; - - $html .= '' . "\n"; - return $html; - } - - function listApps($all = false) { - global $registry; - - $res = array(); - - if ($all) { - $res['ALL'] = _("All Applications"); - } - - foreach ($registry->applications as $app => $params) { - if ($params['status'] == 'heading' || $params['status'] == 'block') { - continue; - } - - if (isset($params['fileroot']) && !is_dir($params['fileroot'])) { - continue; - } - - if (preg_match('/_reports$/', $app) || preg_match('/_tools$/', $app)) { - continue; - } - - if (Babel::hasPermission("module:$app")) { - $res[$app] = sprintf("%s (%s)", $params['name'], $app); - } - } - return $res; - } - - /** - * Returns the value of the specified permission for $userId. - * - * @return mixed Does user have $permission? - */ - function hasPermission($permission, $filter = null, $perm = null) - { - $userId = $GLOBALS['registry']->getAuth(); - $admin = ($userId == 'admin') ? true : false; - $perms = $GLOBALS['injector']->getInstance('Horde_Perms'); - - if ($admin || !$perms->exists('babel:' . $permission)) { - return true; - } - - $allowed = $perms->getPermissions('babel:' . $permission); - - switch ($filter) { - case 'tabs': - if ($perm) { - $allowed = $perms->hasPermission('babel:' . $permission, $GLOBALS['registry']->getAuth(), $perm); - } - break; - } - return $allowed; - } - - /** - * Get the module main Menu. - **/ - function getMenu() - { - global $registry; - - $menu = new Horde_Menu(); - - $menu->addArray(array('url' => Horde::url('index.php'), - 'text' => _("_General"), - 'icon' => 'list.png')); - - if (Babel::hasPermission('view')) { - $menu->addArray(array('url' => Horde::url('view.php'), - 'text' => _("_View"), - 'icon' => 'view.png')); - } - - if (Babel::hasPermission('stats')) { - $menu->addArray(array('url' => Horde::url('stats.php'), - 'text' => _("_Stats"), - 'icon' => 'extract.png')); - } - - if (Babel::hasPermission('extract')) { - $menu->addArray(array('url' => Horde::url('extract.php'), - 'text' => _("_Extract"), - 'icon' => 'extract.png')); - } - - if (Babel::hasPermission('make')) { - $menu->addArray(array('url' => Horde::url('make.php'), - 'text' => _("_Make"), - 'icon' => 'make.png')); - } - - if (Babel::hasPermission('upload')) { - $menu->addArray(array('url' => Horde::url('upload.php'), - 'text' => _("_Upload"), - 'icon' => 'upload.png')); - } - - return $menu; - } - - /** - * Send an Email. - **/ - function sendEmail($email, $type = 'html', $attachments = array()) { - global $client, $scopserv; - - include_once("Mail.php"); - include_once("Mail/mime.php"); - - $headers["From"] = $email['from']; - $headers["Subject"] = $email['subject']; - - $mime = new Mail_Mime(); - if ($type == 'html') { - $mime->setHtmlBody($email['content']); - } else { - $mime->setTxtBody($email['content']); - } - - if (!empty($attachments)) { - foreach ($attachments as $info) { - $mime->addAttachment($info['file'], - $info['type'], - $info['name'], false); - } - } - - $body = $mime->get(); - $hdrs = $mime->headers($headers); - - return $GLOBALS['injector']->getInstance('Horde_Mail')->send($email['to'], $hdrs, $body); - } - - - function RB_init() { - Horde::addScriptFile('effects.js', 'horde'); - Horde::addScriptFile('redbox.js', 'horde'); - } - - function RB_start($secs = 30) { - - $msg = ''; - $msg .= '
'; - $msg .= '' . _("Please be patient ...") . ''; - $msg .= '
'; - $msg .= '
'; - if ($secs < 60) { - $msg .= addslashes(sprintf(_("Can take up to %d seconds !"), $secs)); - } else { - $min = intval($secs / 60); - if ($min == 1) { - $msg .= addslashes(_("Can take up to 1 minute !")); - } else { - $msg .= addslashes(sprintf(_("Can take up to %d minutes !"), $min)); - } - } - - $msg .= '
'; - - $msg .= '
'; - echo ''; - flush(); - } - - function RB_close() { - echo ''; - } - -} diff --git a/babel/lib/Display.php b/babel/lib/Display.php deleted file mode 100644 index fd1fe09ca..000000000 --- a/babel/lib/Display.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @package Babel - */ - -class Translate_Display { - - function header($msg, $msg2 = '') { - global $cnt_i, $registry; - $select_img = Horde::img('alerts/message.png'); - print sprintf('
%s%s%s
', $msg, $msg2, $select_img); - flush(); - } - - function warning($msg, $bold = true) { - global $cnt_i, $registry; - $item = ($cnt_i++ % 2); - $select_img = Horde::img('alerts/warning.png'); - if ($bold) { - print sprintf('
%s%s
', $item, $msg, $select_img); - } else { - print sprintf('
%s%s
', $item, $msg, $select_img); - } - flush(); - } - - function error($msg) { - global $cnt_i, $registry; - $item = ($cnt_i++ % 2); - $select_img = Horde::img('alerts/error.png'); - print sprintf('
%s%s
', $item, $msg, $select_img); - flush(); - } - - function info($msg = "", $bold = true) { - - global $cnt_i, $registry; - - if (empty($msg)) { - echo "
"; - } else { - - $item = ($cnt_i++ % 2); - - $select_img = Horde::img('alerts/select.png'); - if ($bold) { - print sprintf('
%s%s
', $item, $msg, $select_img); - } else { - print sprintf('
%s%s
', $item, $msg, ''); - } - flush(); - } - } - - function parseCharset($headers) - { - if (preg_match('/charset=(.*)/i', $headers, $m)) { - return $m[1]; - } - return $GLOBALS['registry']->getCharset(); - } - - function convert_string($msg) { - global $po; - - $f = array('/</', '/>/'); - $t = array('<', '>'); - $msg = preg_replace($f, $t, $msg); - return Horde_String::convertCharset(html_entity_decode($msg), $GLOBALS['registry']->getCharset(), Translate_Display::parseCharset($po->meta['Content-Type'])); - } - - function display_string($msg) { - global $po; - - $f = array('//'); - $t = array('<', '>'); - $msg = preg_replace($f, $t, $msg); - return Horde_String::convertCharset($msg, Translate_Display::parseCharset($po->meta['Content-Type']), $GLOBALS['registry']->getCharset()); - } - - function get_percent($used, $total) { - if ($total > 0) { - $percent = sprintf("%2.2f", (($used * 100) / $total)); - } else { - $percent = 0; - } - - return $percent; - } - - function create_bargraph ($used, $total, $text = true, $reverse = false, $small = false) { - if ($total > 0) { - $percent = round(($used * 100) / $total); - } else { - $percent = 0; - } - - $html = '', $r1, $r2); - } else { - $r .= sprintf('', $r1, $r2); - } - } - - $r = '
'; - $html .= ''; - $html .= ''; - - if ($percent > 0) { - $html .= ''; - } - - if ($percent != 100) { - $html .= ''; - } - } - - $html .= '
'; - } else { - $html .= ' ' . $percent .'%
'; - - return $html; - } - -} diff --git a/babel/lib/Translate.php b/babel/lib/Translate.php deleted file mode 100644 index 21ea23fb1..000000000 --- a/babel/lib/Translate.php +++ /dev/null @@ -1,748 +0,0 @@ - - * @package Babel - */ - -class Translate { - - function getPath($app) { - if ($app == 'horde') { - $app = ''; - } - return realpath(HORDE_BASE . '/' . $app . '/po/'); - } - - function stats($app, $filter_lang = false) { - global $module, $apps, $dirs, $lang; - - $report = array(); - $dir = Translate::getPath($app); - - $i = 0; - $handle = opendir($dir); - while ($file = readdir($handle)) { - if (preg_match('/(.*)\.po$/', $file, $matches)) { - $locale = $matches[1]; - if ($filter_lang && $locale != $filter_lang) { - continue; - } - - if (!isset(Horde_Nls::$config['languages'][$locale]) || $locale == 'en_US') { - continue; - } - $i++; - - $pofile = $dir . "/$file"; - - $tmppo = new File_Gettext_PO(); - $tmppo->load($pofile); - $fuzzy = 0; - $untranslated = 0; - $translated = 0; - $obsolete = 0; - - foreach($tmppo->status as $msgid => $status) { - if (in_array('untranslated', $status)) { - $untranslated++; - } elseif (in_array('fuzzy', $status)) { - $fuzzy++; - } elseif (in_array('obsolete', $status)) { - $obsolete++; - } else { - $translated++; - } - } - - $all = $translated + $fuzzy + $untranslated; - $percent_done = round($translated / $all * 100, 2); - $report[$locale] = array($all, $percent_done, $translated, $fuzzy, $untranslated, $obsolete); - } - } - uasort ($report, 'my_usort_function'); - - return $report; - } - - function sanity_check() - { - - /* Sanity checks */ - if (!extension_loaded('gettext')) { - Translate_Display::error(_("Gettext extension not found!")); - } - - Translate_Display::info(_("Loading libraries...")); - $libs_found = true; - - foreach (array('Console_Getopt' => 'Console/Getopt.php', - 'Console_Table' => 'Console/Table.php', - 'File_Find' => 'File/Find.php') - as $class => $file) { - @include_once $file; - if (class_exists($class)) { - // Translate_Display::info("$class ...", false); - } else { - Translate_Display::error(sprintf(_("%s not found."), $class)); - $libs_found = false; - } - } - - if (!$libs_found) { - Translate_Display::info(); - Translate_Display::info(_("Make sure that you have PEAR installed and in your include path.")); - Translate_Display::info('include_path: ' . ini_get('include_path')); - } - } - - function check_binaries() - { - global $gettext_version, $c; - - Translate_Display::info(_("Searching gettext binaries...")); - require_once 'System.php'; - foreach (array('gettext', 'msgattrib', 'msgcat', 'msgcomm', 'msgfmt', 'msginit', 'msgmerge', 'xgettext') as $binary) { - $GLOBALS[$binary] = System::which($binary); - if ($GLOBALS[$binary]) { - // Translate_Display::info("$binary ... found: " . $GLOBALS[$binary], false); - } else { - Translate_Display::error(sprintf(_("%s not found."), $binary)); - } - } - - $out = ''; - exec($GLOBALS['gettext'] . ' --version', $out, $ret); - $split = explode(' ', $out[0]); - // Translate_Display::info('gettext version: ' . $split[count($split) - 1]); - $gettext_version = explode('.', $split[count($split) - 1]); - if ($gettext_version[0] == 0 && $gettext_version[1] < 12) { - $GLOBALS['php_support'] = false; - Translate_Display::info(); - Translate_Display::warning(_("Warning: Your gettext version is too old and does not support PHP natively.")); - Translate_Display::warning(_("Not all strings will be extracted."), false); - } else { - $GLOBALS['php_support'] = true; - } - Translate_Display::info(); - } - - function search_file($file, $dir = '.', $local = false) - { - static $ff; - if (!isset($ff)) { - $ff = new File_Find(); - } - - if (substr($file, 0, 1) != '/') { - $file = "/$file/"; - } - - if ($local) { - $files = $ff->glob($file, $dir, 'perl'); - $files = array_map(create_function('$file', 'return "' . $dir . '/' . '" . $file;'), $files); - return $files; - } else { - return $ff->search($file, $dir, 'perl'); - } - } - - function search_ext($ext, $dir = '.', $local = false) - { - return Translate::search_file(".+\\.$ext\$", $dir, $local); - } - - function get_po_files($dir) - { - $langs = Translate::search_ext('po', $dir); - if (($key = array_search($dir . '/' . 'messages.po', $langs)) !== false) { - unset($langs[$key]); - } - if (($key = array_search($dir . '/' . 'compendium.po', $langs)) !== false) { - unset($langs[$key]); - } - return $langs; - } - - function get_languages($dir) - { - chdir($dir); - $langs = get_po_files('po'); - $langs = array_map(create_function('$lang', 'return str_replace("po" . '/', "", str_replace(".po", "", $lang));'), $langs); - return $langs; - } - - function search_applications() - { - $dirs = array(); - $horde = false; - if (@is_dir(HORDE_BASE . '/' . 'po')) { - $dirs[] = HORDE_BASE; - $horde = true; - } - $dh = @opendir(HORDE_BASE); - if ($dh) { - while ($entry = @readdir($dh)) { - $dir = HORDE_BASE . '/' . $entry; - if (is_dir($dir) && - substr($entry, 0, 1) != '.' && - fileinode(HORDE_BASE) != fileinode($dir)) { - $sub = opendir($dir); - if ($sub) { - while ($subentry = readdir($sub)) { - if ($subentry == 'po' && is_dir($dir . '/' . $subentry)) { - $dirs[] = $dir; - if ($entry == 'horde') { - $horde = true; - } - break; - } - } - } - } - } - if (!$horde) { - array_unshift($dirs, HORDE_BASE); - } - } - - return $dirs; - } - - function strip_horde($file) - { - if (is_array($file)) { - return array_map(create_function('$file', 'return Translate::strip_horde($file);'), $file); - } else { - return str_replace(HORDE_BASE . '/', '', $file); - } - } - - function commit($help_only = false) - { - global $apps, $dirs, $lang, $module; - - $docs = false; - $files = array(); - for ($i = 0; $i < count($dirs); $i++) { - if (!empty($module) && $module != $apps[$i]) continue; - if ($apps[$i] == 'horde') { - $dirs[] = $dirs[$i] . '/' . 'admin'; - $apps[] = 'horde/admin'; - if (!empty($module)) { - $module = 'horde/admin'; - } - } - if (empty($lang)) { - if ($help_only) { - $files = array_merge($files, Translate::strip_horde(Translate::search_ext('xml', $dirs[$i] . '/' . 'locale'))); - } else { - $files = array_merge($files, Translate::strip_horde(Translate::get_po_files($dirs[$i] . '/' . 'po'))); - $files = array_merge($files, Translate::strip_horde(Translate::search_file('^[a-z]{2}_[A-Z]{2}', $dirs[$i] . '/' . 'locale', true))); - } - } else { - if ($help_only) { - if (!@file_exists($dirs[$i] . '/' . 'locale' . '/' . $lang . '/' . 'help.xml')) continue; - } else { - if (!@file_exists($dirs[$i] . '/po/' . $lang . '.po')) continue; - $files[] = Translate::strip_horde($dirs[$i] . '/' . 'po' . '/' . $lang . '.po'); - } - $files[] = Translate::strip_horde($dirs[$i] . '/' . 'locale' . '/' . $lang); - } - if ($docs && !$help_only && $apps[$i]) { - $files[] = Translate::strip_horde($dirs[$i] . '/' . 'docs'); - if ($apps[$i] == 'horde') { - $horde_conf = $dirs[array_search('horde', $dirs)] . '/' . 'config' . '/'; - $files[] = Translate::strip_horde($horde_conf . 'nls.php.dist'); - } - } - } - chdir(HORDE_BASE); - if (count($files)) { - if ($docs) { - Translate_Display::info(_("Adding new files to repository:")); - $sh = 'cvs add'; - foreach ($files as $file) { - if (strstr($file, 'locale') || strstr($file, '.po')) { - $sh .= " $file"; - Translate_Display::info($file, false); - } - } - $sh .= '; cvs add'; - foreach ($files as $file) { - if (strstr($file, 'locale')) { - if ($help_only) { - $sh .= ' ' . $file . '/' . '*.xml'; - Translate_Display::info($file . '/' . '*.xml', false); - } else { - $sh .= ' ' . $file . '/' . '*.xml ' . $file . '/' . 'LC_MESSAGES'; - Translate_Display::info($file . '/' . "*.xml\n$file" . '/' . 'LC_MESSAGES', false); - } - } - } - if (!$help_only) { - $sh .= '; cvs add'; - foreach ($files as $file) { - if (strstr($file, 'locale')) { - $add = $file . '/' . 'LC_MESSAGES' . '/' . '*.mo'; - $sh .= ' ' . $add; - Translate_Display::info($add, false); - } - } - } - Translate_Display::info(); - system($sh); - Translate_Display::info(); - } - Translate_Display::header(_("Committing:")); - Translate_Display::info(implode(' ', $files), false); - if (!empty($lang)) { - $lang = ' ' . $lang; - } - if (empty($msg)) { - if ($docs) { - $msg = "Add $lang translation."; - } elseif ($help_only) { - $msg = "Update $lang help file."; - } else { - $msg = "Update $lang translation."; - } - } - $sh = 'cvs commit -m "' . $msg . '" ' . implode(' ', $files); - system($sh); - } - } - - function xtract() - { - global $module, $apps, $dirs, $gettext_version; - - require_once 'Horde/Array.php'; - if ($GLOBALS['php_support']) { - $language = 'PHP'; - } else { - $language = 'C++'; - } - for ($i = 0; $i < count($dirs); $i++) { - if (!empty($module) && $module != $apps[$i]) { - continue; - } - Translate_Display::header(sprintf(_("Extracting from %s... "), $apps[$i])); - chdir($dirs[$i]); - if ($apps[$i] == 'horde') { - $files = Translate::search_ext('php', '.', true); - foreach (array('admin', 'framework', 'lib', 'services', 'templates', 'util', 'config' . '/' . 'themes') as $search_dir) { - $files = array_merge($files, Translate::search_ext('(php|inc|js)', $search_dir)); - } - $files = array_merge($files, Translate::search_ext('(php|dist)', 'config')); - $sh = $GLOBALS['xgettext'] . ' --language=' . $language . - ' --from-code=iso-8859-1 --keyword=_ --sort-output --copyright-holder="Horde Project"'; - if ($gettext_version[0] > 0 || $gettext_version[1] > 11) { - $sh .= ' --msgid-bugs-address="dev@lists.horde.org"'; - } - $file = $dirs[$i] . '/' . 'po' . '/' . $apps[$i] . '.pot'; - if (file_exists($file) && !is_writable($file)) { - Translate_Display::error(sprintf(_('%s is not writable.', $file))); - } - $tmp_file = $file . '.tmp.pot'; - $sh .= ' -o ' . $tmp_file . ' ' . implode(' ', $files); - if (@file_exists($dirs[$i] . '/po/translation.php')) { - $sh .= ' po/translation.php'; - } - exec($sh); - } else { - $files = Translate::search_ext('(php|inc|js)'); - $files = array_filter($files, create_function('$file', 'return substr($file, 0, 9) != "./config/";')); - $files = array_merge($files, Translate::search_ext('(php|dist)', 'config')); - $sh = $GLOBALS['xgettext'] . ' --language=' . $language . - ' --keyword=_ --sort-output --force-po --copyright-holder="Horde Project"'; - if ($gettext_version[0] > 0 || $gettext_version[1] > 11) { - $sh .= ' --msgid-bugs-address="support@scopserv.com"'; - } - $file = 'po' . '/' . $apps[$i] . '.pot'; - if (file_exists($file) && !is_writable($file)) { - Translate_Display::error((sprintf(_("%s is not writable."), $file))); - } - $tmp_file = $file . '.tmp.pot'; - $sh .= ' -o ' . $tmp_file . ' ' . implode(' ', $files); - exec($sh); - } - - if (file_exists($tmp_file)) { - $files = Translate::search_ext('html', 'templates'); - $tmp = fopen($file . '.templates', 'w'); - foreach ($files as $template) { - $fp = fopen($template, 'r'); - $lineno = 0; - while (($line = fgets($fp, 4096)) !== false) { - $lineno++; - $offset = 0; - while (($left = strpos($line, '', $offset)) !== false) { - $left += 9; - $buffer = ''; - $linespan = 0; - while (($end = strpos($line, '', $left)) === false) { - $buffer .= substr($line, $left); - $left = 0; - $line = fgets($fp, 4096); - $linespan++; - if ($line === false) { - Translate_Display::error((sprintf(_(" tag not closed in file %s.\nOpening tag found in line %d."), $template, $lineno))); - break 2; - } - } - $buffer .= substr($line, $left, $end - $left); - fwrite($tmp, "#: $template:$lineno\n"); - fwrite($tmp, 'msgid "' . str_replace(array('"', "\n"), array('\"', "\\n\"\n\""), $buffer) . "\"\n"); - fwrite($tmp, 'msgstr ""' . "\n\n"); - - $offset = $end + 10; - } - } - fclose($fp); - } - fclose($tmp); - $sh = $GLOBALS['msgcomm'] . " --more-than=0 --sort-output \"$tmp_file\" \"$file.templates\" --output-file \"$tmp_file\""; - exec($sh); - unlink($file . '.templates'); - - if (file_exists($file)) { - $diff = array_diff(file($tmp_file), file($file)); - $diff = preg_grep('/^"POT-Creation-Date:/', $diff, PREG_GREP_INVERT); - } - } - - if (!file_exists($file) || count($diff)) { - @unlink($file); - rename($tmp_file, $file); - Translate_Display::info(_("Updated!")); - } else { - @unlink($tmp_file); - Translate_Display::info(_("Not changed!")); - } - } - } - - function merge() - { - global $apps, $dirs, $lang, $module; - - $compendium = ' --compendium="' . HORDE_BASE . '/' . 'po' . '/' . 'compendium.po"'; - // $compendium = ' --compendium=' . $option[1]; - // $compendium = ''; - - if (!isset($lang) && !empty($compendium)) { - Translate_Display::error(_("Error: No locale specified.")); - Translate_Display::info(); - usage(); - } - - Translate::cleanup(); - - for ($i = 0; $i < count($dirs); $i++) { - if (!empty($module) && $module != $apps[$i]) { - continue; - } - Translate_Display::header(sprintf(_("Merging translation for module %s..."), $apps[$i])); - $dir = $dirs[$i] . '/' . 'po' . '/'; - if (empty($lang)) { - $langs = get_languages($dirs[$i]); - } else { - if (!@file_exists($dir . $lang . '.po')) { - Translate_Display::info(_("Skipped...")); - Translate_Display::info(); - continue; - } - $langs = array($lang); - } - foreach ($langs as $locale) { - Translate_Display::info(sprintf(_("Merging locale %s..."), $locale)); - $sh = $GLOBALS['msgmerge'] . ' --update -v' . $compendium . ' "' . $dir . $locale . '.po" "' . $dir . $apps[$i] . '.pot"'; - exec($sh); - Translate_Display::info(_("Done!")); - } - } - } - - function compendium() - { - global $dirs, $lang, $module; - - $dir = HORDE_BASE . '/' . 'po' . '/'; - $add = ''; - if (!isset($lang)) { - Translate_Display::error(_("Error: No locale specified.")); - Translate_Display::info(); - usage(); - } - Translate_Display::info(sprintf(_("Merging all %s.po files to the compendium... "), $lang)); - $pofiles = array(); - for ($i = 0; $i < count($dirs); $i++) { - $pofile = $dirs[$i] . '/' . 'po' . '/' . $lang . '.po'; - if (file_exists($pofile)) { - $pofiles[] = $pofile; - } - } - if (!empty($dir) && substr($dir, -1) != '/') { - $dir .= '/'; - } - $sh = $GLOBALS['msgcat'] . ' --sort-output ' . implode(' ', $pofiles) . $add . ' > ' . $dir . 'compendium.po '; - exec($sh, $out, $ret); - - if ($ret == 0) { - Translate_Display::info(_("Done!")); - } else { - Translate_Display::error(_("Failed!")); - } - } - - function init() - { - global $module, $apps, $dirs, $lang, $module; - - if (empty($lang)) { $lang = getenv('LANG'); } - for ($i = 0; $i < count($dirs); $i++) { - if (@file_exists($dirs[$i] . '/po/' . $lang . '.po')) { - continue; - } - if (!empty($module) && $module != $apps[$i]) { continue; } - $package = ucfirst($apps[$i]); - $package_u = Horde_String::upper($apps[$i]); - @include $dirs[$i] . '/lib/version.php'; - $version = eval('return(defined("' . $package_u . '_VERSION") ? ' . $package_u . '_VERSION : "???");'); - Translate_Display::header(sprintf(_("Initializing module %s..."), $apps[$i])); - if (!@file_exists($dirs[$i] . '/po/' . $apps[$i] . '.pot')) { - Translate_Display::error(_("Failed!")); - Translate_Display::info(sprintf(_("%s not found. Run 'Extract' first."), $dirs[$i] . '/' . 'po' . '/' . $apps[$i] . '.pot')); - continue; - } - $dir = $dirs[$i] . '/' . 'po' . '/'; - $sh = $GLOBALS['msginit'] . ' --no-translator -i ' . $dir . $apps[$i] . '.pot ' . - (!empty($lang) ? ' -o ' . $dir . $lang . '.po --locale=' . $lang : ''); - - if (!empty($lang) && !OS_WINDOWS) { - $pofile = $dirs[$i] . '/po/' . $lang . '.po'; - $sh .= "; sed 's/PACKAGE package/$package package/' $pofile " . - "| sed 's/PACKAGE VERSION/$package $version/' " . - "| sed 's/messages for PACKAGE/messages for $package/' " . - "| sed 's/Language-Team: none/Language-Team: i18n@lists.horde.org/' " . - "> $pofile.tmp"; - } - exec($sh, $out, $ret); - rename($pofile . '.tmp', $pofile); - if ($ret == 0) { - Translate_Display::info(_("Done!")); - } else { - Translate_Display::error(_("Failed!")); - } - Translate_Display::info(); - } - } - - function make() - { - global $apps, $dirs, $lang, $module; - - $compendium = HORDE_BASE . '/' . 'po' . '/' . 'compendium.po'; - $save_stats = true; - - $horde = array_search('horde', $dirs); - $horde_msg = array(); - $stats_array = array(); - - for ($i = 0; $i < count($dirs); $i++) { - if (!empty($module) && $module != $apps[$i]) continue; - Translate_Display::header(sprintf(_("Building MO files for module %s..."), $apps[$i])); - if (empty($lang)) { - $langs = get_languages($dirs[$i]); - } else { - if (!@file_exists($dirs[$i] . '/' . 'po' . '/' . $lang . '.po')) { - Translate_Display::info(_("Skipped...")); - Translate_Display::info(); - continue; - } - $langs = array($lang); - } - foreach ($langs as $locale) { - Translate_Display::info(sprintf(_("Building locale %s..."), $locale)); - $dir = $dirs[$i] . '/' . 'locale' . '/' . $locale . '/' . 'LC_MESSAGES'; - if (!is_dir($dir)) { - require_once 'System.php'; - if (!@System::mkdir("-p $dir")) { - Translate_Display::error(sprintf(_("Warning: Could not create locale directory for locale %s:"), $locale)); - Translate_Display::info($dir, false); - Translate_Display::info(); - continue; - } - } - - /* Convert to unix linebreaks. */ - $pofile = $dirs[$i] . '/' . 'po' . '/' . $locale . '.po'; - $fp = fopen($pofile, 'r'); - $content = fread($fp, filesize($pofile)); - fclose($fp); - - $content = str_replace("\r", '', $content); - $fp = fopen($pofile, 'wb'); - fwrite($fp, $content); - fclose($fp); - - /* Check PO file sanity. */ - $sh = $GLOBALS['msgfmt'] . " --check \"$pofile\" 2>&1"; - exec($sh, $out, $ret); - if ($ret != 0) { - Translate_Display::error(_("Warning: an error has occured:")); - Translate_Display::info(implode("\n", $out)); - Translate_Display::info(); - if ($apps[$i] == 'horde') { - continue 2; - } - continue; - } - - /* Compile MO file. */ - $sh = $GLOBALS['msgfmt'] . ' --statistics -o "' . $dir . '/' . $apps[$i] . '.mo"'; - if ($apps[$i] != 'horde') { - $horde_po = $dirs[$horde] . '/' . 'po' . '/' . $locale . '.po'; - if (!@is_readable($horde_po)) { - Translate_Display::error(sprintf(_("Warning: the Horde PO file for the locale %s does not exist:"), $locale)); - Translate_Display::info($horde_po); - Translate_Display::info(); - $sh .= $dirs[$i] . '/' . 'po' . '/' . $locale . '.po'; - } else { - $sh = "export LANG=C ; " . $GLOBALS['msgcomm'] . " --more-than=0 --sort-output \"$pofile\" \"$horde_po\" | $sh -"; - } - } else { - $sh .= $pofile; - } - $sh .= ' 2>&1'; - $out = ''; - - exec($sh, $out, $ret); - - if ($ret == 0) { - Translate_Display::info(_("Done!")); - $messages = array(0, 0, 0); - if (preg_match('/(\d+) translated/', $out[0], $match)) { - $messages[0] = $match[1]; - if (isset($horde_msg[$locale])) { - $messages[0] -= $horde_msg[$locale][0]; - if ($messages[0] < 0) $messages[0] = 0; - } - } - if (preg_match('/(\d+) fuzzy/', $out[0], $match)) { - $messages[1] = $match[1]; - if (isset($horde_msg[$locale])) { - $messages[1] -= $horde_msg[$locale][1]; - if ($messages[1] < 0) $messages[1] = 0; - } - } - if (preg_match('/(\d+) untranslated/', $out[0], $match)) { - $messages[2] = $match[1]; - if (isset($horde_msg[$locale])) { - $messages[2] -= $horde_msg[$locale][2]; - if ($messages[2] < 0) $messages[2] = 0; - } - } - if ($apps[$i] == 'horde') { - $horde_msg[$locale] = $messages; - } - $stats_array[$apps[$i]][$locale] = $messages; - } else { - Translate_Display::error(_("Failed!")); - exec($sh, $out, $ret); - Translate_Display::info(implode("\n", $out)); - } - if (count($langs) > 1) { - continue; - } - - /* Merge translation into compendium. */ - if (!empty($compendium)) { - Translate_Display::header(sprintf(_("Merging the PO file for %s to the compendium..."), $apps[$i])); - if (!empty($dir) && substr($dir, -1) != '/') { - $dir .= '/'; - } - $sh = $GLOBALS['msgcat'] . " --sort-output \"$compendium\" \"$pofile\" > \"$compendium.tmp\""; - $out = ''; - exec($sh, $out, $ret); - @unlink($compendium); - rename($compendium . '.tmp', $compendium); - if ($ret == 0) { - Translate_Display::info(_("Done!")); - } else { - Translate_Display::error(_("Failed!")); - } - } - Translate_Display::info(); - } - } - if (empty($module)) { - Translate_Display::header(_("Results:")); - } else { - Translate_Display::header(_("Results (including Horde):")); - } - - echo '
'; - echo ''; - echo sprintf('', 'Module', 'Language', 'Translated', 'Fuzzy', 'Untranslated'); - - $i = 0; - foreach($stats_array as $app => $info) { - foreach($info as $locale => $message) { - echo sprintf('', - ($i++ %2), $app, $locale, $messages[0], $messages[1], $messages[2]); - } - } - echo '
%s%s%s%s%s
%s%s%s%s%s
'; - - if ($save_stats) { - $fp = @fopen('/tmp/translation_stats.txt', 'w'); - if ($fp) { - fwrite($fp, serialize($stats_array)); - fclose($fp); - } - } - } - - function cleanup($keep_untranslated = false) - { - global $apps, $dirs, $lang, $module; - - for ($i = 0; $i < count($dirs); $i++) { - if (!empty($module) && $module != $apps[$i]) { continue; } - Translate_Display::header(sprintf(_("Cleaning up PO files for module %s..."), $apps[$i])); - if (empty($lang)) { - $langs = get_languages($dirs[$i]); - } else { - if (!@file_exists($dirs[$i] . '/' . 'po' . '/' . $lang . '.po')) { - Translate_Display::info(_("Skipped...")); - Translate_Display::info(); - continue; - } - $langs = array($lang); - } - foreach ($langs as $locale) { - Translate_Display::info(sprintf(_("Cleaning up locale %s..."), $locale)); - $pofile = $dirs[$i] . '/' . 'po' . '/' . $locale . '.po'; - $sh = $GLOBALS['msgattrib'] . ($keep_untranslated ? '' : ' --translated') . " --no-obsolete --no-fuzzy --force-po $pofile > $pofile.tmp"; - $out = ''; - exec($sh, $out, $ret); - if ($ret == 0) { - @unlink($pofile); - rename($pofile . '.tmp', $pofile); - Translate_Display::info(_("Done!")); - } else { - @unlink($pofile . '.tmp', $pofile); - Translate_Display::error(_("Failed!")); - } - Translate_Display::info(); - } - } - } -} - diff --git a/babel/lib/Translate_Help.php b/babel/lib/Translate_Help.php deleted file mode 100644 index 36cf332ea..000000000 --- a/babel/lib/Translate_Help.php +++ /dev/null @@ -1,238 +0,0 @@ - - * @package Babel - */ - -class Translate_Help { - function update_help() - { - global $dirs, $apps, $last_error_msg, $lang, $module; - - $files = array(); - for ($i = 0; $i < count($dirs); $i++) { - if (!empty($module) && $module != $apps[$i]) { continue; } - if (!is_dir("$dirs[$i]/locale")) continue; - if ($apps[$i] == 'horde') { - $dirs[] = $dirs[$i] . '/' . 'admin'; - $apps[] = 'horde/admin'; - if (!empty($module)) { - $module = 'horde/admin'; - } - } - if (empty($lang)) { - $files = search_file('help.xml', $dirs[$i] . '/' . 'locale'); - } else { - $files = array($dirs[$i] . '/' . 'locale' . '/' . $lang . '/' . 'help.xml'); - } - $file_en = $dirs[$i] . '/' . 'locale' . '/' . 'en' . '/' . 'help.xml'; - if (!@file_exists($file_en)) { - Translate_Display::info(sprintf(_("Warning: There doesn't yet exist a help file for %s."), $apps[$i])); - Translate_Display::info(); - continue; - } - foreach ($files as $file_loc) { - $locale = substr($file_loc, 0, strrpos($file_loc, '/')); - $locale = substr($locale, strrpos($locale, '/') + 1); - if ($locale == 'en') continue; - if (!@file_exists($file_loc)) { - Translate_Display::info(sprintf(_("Warning: The %s help file for %s doesn't yet exist. Creating a new one."), $locale, $apps[$i])); - $dir_loc = substr($file_loc, 0, -9); - if (!is_dir($dir_loc)) { - require_once 'System.php'; - if (!@System::mkdir("-p $dir_loc")) { - Translate_Display::error(sprintf(_("Warning: Could not create locale directory for locale %s:"), $locale)); - Translate_Display::info($dir_loc, false); - Translate_Display::info(); - continue; - } - } - - if (!@copy($file_en, $file_loc)) { - Translate_Display::error(sprintf(_("Warning: Could not copy %s to %s"), $file_en, $file_loc)); - } - Translate_Display::info(); - continue; - } - Translate_Display::info(sprintf(_("Updating %s help file for %s."), $locale, $apps[$i])); - $fp = fopen($file_loc, 'r'); - $line = fgets($fp); - fclose($fp); - if (!strstr($line, 'document_element(); - $help_loc = $doc_loc->document_element(); - $help_new = $help_loc->clone_node(); - $entries_loc = array(); - $entries_new = array(); - $count_uptodate = 0; - $count_new = 0; - $count_changed = 0; - $count_unknown = 0; - foreach ($doc_loc->get_elements_by_tagname('entry') as $entry) { - $entries_loc[$entry->get_attribute('id')] = $entry; - } - foreach ($doc_en->get_elements_by_tagname('entry') as $entry) { - $id = $entry->get_attribute('id'); - if (array_key_exists($id, $entries_loc)) { - if ($entries_loc[$id]->has_attribute('md5') && - md5($entry->get_content()) != $entries_loc[$id]->get_attribute('md5')) { - $comment = $doc_loc->create_comment(" English entry:\n" . str_replace('--', '--', $doc_loc->dump_node($entry))); - $entries_loc[$id]->append_child($comment); - $entry_new = $entries_loc[$id]->clone_node(true); - $entry_new->set_attribute('state', 'changed'); - $count_changed++; - } else { - if (!$entries_loc[$id]->has_attribute('state')) { - $comment = $doc_loc->create_comment(" English entry:\n" . str_replace('--', '--', $doc_loc->dump_node($entry))); - $entries_loc[$id]->append_child($comment); - $entry_new = $entries_loc[$id]->clone_node(true); - $entry_new->set_attribute('state', 'unknown'); - $count_unknown++; - } else { - $entry_new = $entries_loc[$id]->clone_node(true); - $count_uptodate++; - } - } - } else { - $entry_new = $entry->clone_node(true); - $entry_new->set_attribute('state', 'new'); - $count_new++; - } - $entries_new[] = $entry_new; - } - $doc_new->append_child($doc_new->create_comment(' $' . 'Horde$ ')); - foreach ($entries_new as $entry) { - $help_new->append_child($entry); - } - Translate_Display::info(sprintf(_("Entries: %d total, %d up-to-date, %d new, %d changed, %d unknown"), - $count_uptodate + $count_new + $count_changed + $count_unknown, - $count_uptodate, $count_new, $count_changed, $count_unknown), false); - $doc_new->append_child($help_new); - $output = $doc_new->dump_mem(true, $encoding); - $fp = fopen($file_loc, 'w'); - $line = fwrite($fp, $output); - fclose($fp); - Translate_Display::info(sprintf(_("%d bytes written."), strlen($output)), false); - Translate_Display::info(); - } - } - } - - function make_help() - { - global $dirs, $apps, $lang, $module; - - $files = array(); - for ($i = 0; $i < count($dirs); $i++) { - if (!empty($module) && $module != $apps[$i]) continue; - if (!is_dir("$dirs[$i]/locale")) continue; - if ($apps[$i] == 'horde') { - $dirs[] = $dirs[$i] . '/' . 'admin'; - $apps[] = 'horde/admin'; - if (!empty($module)) { - $module = 'horde/admin'; - } - } - if (empty($lang)) { - $files = search_file('help.xml', $dirs[$i] . '/' . 'locale'); - } else { - $files = array($dirs[$i] . '/' . 'locale' . '/' . $lang . '/' . 'help.xml'); - } - $file_en = $dirs[$i] . '/' . 'locale' . '/' . 'en' . '/' . 'help.xml'; - if (!@file_exists($file_en)) { - continue; - } - foreach ($files as $file_loc) { - if (!@file_exists($file_loc)) { - Translate_Display::info(_("Skipped...")); - Translate_Display::info(); - continue; - } - $locale = substr($file_loc, 0, strrpos($file_loc, '/')); - $locale = substr($locale, strrpos($locale, '/') + 1); - if ($locale == 'en') continue; - Translate_Display::info(sprintf(_("Updating %s help file for %s."), ($locale), ($apps[$i]))); - $fp = fopen($file_loc, 'r'); - $line = fgets($fp); - fclose($fp); - if (!strstr($line, 'document_element(); - $md5_en = array(); - $count_all = 0; - $count = 0; - foreach ($doc_en->get_elements_by_tagname('entry') as $entry) { - $md5_en[$entry->get_attribute('id')] = md5($entry->get_content()); - } - foreach ($doc_loc->get_elements_by_tagname('entry') as $entry) { - foreach ($entry->child_nodes() as $child) { - if ($child->node_type() == XML_COMMENT_NODE && strstr($child->node_value(), 'English entry')) { - $entry->remove_child($child); - } - } - $count_all++; - $id = $entry->get_attribute('id'); - if (!array_key_exists($id, $md5_en)) { - Translate_Display::info(sprintf(_("No entry with the id '%s' exists in the original help file."), $id)); - } else { - $entry->set_attribute('md5', $md5_en[$id]); - $entry->set_attribute('state', 'uptodate'); - $count++; - } - } - $output = $doc_loc->dump_mem(true, $encoding); - $fp = fopen($file_loc, 'w'); - $line = fwrite($fp, $output); - fclose($fp); - - Translate_Display::info(sprintf(_("%d of %d entries marked as up-to-date"), $count, $count_all), false); - Translate_Display::info(); - } - } - } -} diff --git a/babel/lib/base.php b/babel/lib/base.php deleted file mode 100644 index 149b82885..000000000 --- a/babel/lib/base.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @package Babel - */ - -/* Check for a prior definition of HORDE_BASE (perhaps by an auto_prepend_file - * definition for site customization). */ -if (!defined('HORDE_BASE')) { - @define('HORDE_BASE', dirname(__FILE__) . '/../..'); -} - -if (!defined('BABEL_BASE')) { - @define('BABEL_BASE', dirname(__FILE__) . '/..'); -} - -/* Load the Horde Framework core, and set up inclusion paths. */ -require_once HORDE_BASE . '/lib/core.php'; - -/* Registry. */ -$registry = new Horde_Registry(); - -try { - $registry->pushApp('babel', array('logintasks' => true)); -} catch (Horde_Exception $e) { - $registry->authenticateFailure('babel', $e); -} - -$conf = &$GLOBALS['conf']; -@define('BABEL_TEMPLATES', $registry->get('templates')); - -/* Babel base library */ -require_once BABEL_BASE . '/lib/Babel.php'; -require_once BABEL_BASE . '/lib/Translate.php'; -require_once BABEL_BASE . '/lib/Translate_Help.php'; -require_once BABEL_BASE . '/lib/Display.php'; - -/* Gettext (PO) */ -require_once BABEL_BASE . '/lib/Gettext/PO.php'; - -/* Form and Variables */ -require_once 'Horde/Form.php'; -require_once 'Horde/Form/Renderer.php'; -require_once 'Horde/Form/Action.php'; - -/* Templates */ -$template = $injector->createInstance('Horde_Template'); - -/* Module selection */ -$app = Horde_Util::getFormData('module'); - -/* Language selection */ -if (($lang = Horde_Util::getFormData('display_language')) !== null) { - $_SESSION['babel']['language'] = $lang; -} elseif (isset($_SESSION['babel']['language'])) { - $lang = $_SESSION['babel']['language']; -} else { - - $tests = Horde_Nls::$config['languages']; - - // Unset English - unset($tests['en_US']); - - foreach($tests as $dir => $desc) { - if (!Babel::hasPermission("language:$dir")) { - continue; - } else { - $lang = $dir; - break; - } - } - $_SESSION['babel']['language'] = $lang; -} - -/* Set up the template fields. */ -$template->set('menu', Babel::getMenu()->render()); - -Horde::startBuffer(); -$notification->notify(array('listeners' => 'status')); -$template->set('notify', Horde::endBuffer()); - -$template->set('lang', Babel::displayLanguage()); -$fmenu = Babel::LanguageSelection(); - -// Only display the Module Selection widget if an application has been set -if ($app) { - $fmenu .= Babel::ModuleSelection(); -} -$template->set('fmenu', $fmenu); - -if ($lang && !Babel::hasPermission("language:$lang")) { - throw new Horde_Exception(sprintf(_("Access forbidden to '%s'."), $lang)); -} - -if ($app && !Babel::hasPermission("module:$app")) { - throw new Horde_Exception(sprintf(_("Access forbidden to '%s'."), $app)); -} - -/* Custom sort function */ -function my_usort_function($a, $b) -{ - if ($a[1] > $b[1]) { return -1; } - if ($a[1] < $b[1]) { return 1; } - return 0; -} diff --git a/babel/locale/.htaccess b/babel/locale/.htaccess deleted file mode 100644 index 3a4288278..000000000 --- a/babel/locale/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/babel/locale/babel.pot b/babel/locale/babel.pot deleted file mode 100644 index 2d8647c3d..000000000 --- a/babel/locale/babel.pot +++ /dev/null @@ -1,563 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Horde Project -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: dev@lists.horde.org\n" -"POT-Creation-Date: 2010-08-17 17:46+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: lib/Translate_Help.php:141 -#, php-format -msgid "%d bytes written." -msgstr "" - -#: lib/Translate_Help.php:233 -#, php-format -msgid "%d of %d entries marked as up-to-date" -msgstr "" - -#: lib/Translate.php:349 lib/Translate.php:368 -#, php-format -msgid "%s is not writable." -msgstr "" - -#: extract.php:65 lib/Translate.php:91 lib/Translate.php:114 -#, php-format -msgid "%s not found." -msgstr "" - -#: lib/Translate.php:520 -#, php-format -msgid "%s not found. Run 'Extract' first." -msgstr "" - -#: view.php:303 -#, php-format -msgid "%s to %s of %s" -msgstr "" - -#: lib/Translate.php:394 -#, php-format -msgid "" -" tag not closed in file %s.\n" -"Opening tag found in line %d." -msgstr "" - -#: viewsource.php:30 -#, php-format -msgid "Access denied to %s" -msgstr "" - -#: lib/base.php:97 lib/base.php:101 -#, php-format -msgid "Access forbidden to '%s'." -msgstr "" - -#: lib/Translate.php:267 -msgid "Adding new files to repository:" -msgstr "" - -#: view.php:225 view.php:227 -msgid "All" -msgstr "" - -#: lib/Babel.php:53 lib/Babel.php:135 -msgid "All Applications" -msgstr "" - -#: templates/index.php:50 -msgid "Build binary MO files from the specified PO files." -msgstr "" - -#: lib/Translate.php:559 -#, php-format -msgid "Building MO files for module %s..." -msgstr "" - -#: lib/Translate.php:571 -#, php-format -msgid "Building locale %s..." -msgstr "" - -#: lib/Babel.php:284 -#, php-format -msgid "Can take up to %d minutes !" -msgstr "" - -#: lib/Babel.php:278 -#, php-format -msgid "Can take up to %d seconds !" -msgstr "" - -#: lib/Babel.php:282 -msgid "Can take up to 1 minute !" -msgstr "" - -#: view.php:444 -msgid "Cancel" -msgstr "" - -#: lib/Translate.php:718 -#, php-format -msgid "Cleaning up PO files for module %s..." -msgstr "" - -#: lib/Translate.php:730 -#, php-format -msgid "Cleaning up locale %s..." -msgstr "" - -#: commit.php:47 templates/index.php:55 lib/Application.php:67 -msgid "Commit" -msgstr "" - -#: commit.php:41 -msgid "Commit PO files ..." -msgstr "" - -#: templates/index.php:56 -msgid "Commit translations to the SVN server." -msgstr "" - -#: lib/Translate.php:301 -msgid "Committing:" -msgstr "" - -#: extract.php:114 lib/Translate.php:466 lib/Translate.php:497 -#: lib/Translate.php:538 lib/Translate.php:628 lib/Translate.php:676 -#: lib/Translate.php:738 -msgid "Done!" -msgstr "" - -#: templates/index.php:25 lib/Application.php:60 -msgid "Download" -msgstr "" - -#: download.php:14 -msgid "Download File" -msgstr "" - -#: templates/index.php:26 -msgid "Download all current PO files." -msgstr "" - -#: edit.php:75 -msgid "Edit" -msgstr "" - -#: view.php:166 -msgid "Edit Header" -msgstr "" - -#: view.php:231 -msgid "Edit Mode" -msgstr "" - -#: edit.php:52 view.php:440 -msgid "Edit Translation" -msgstr "" - -#: lib/Translate_Help.php:133 -#, php-format -msgid "Entries: %d total, %d up-to-date, %d new, %d changed, %d unknown" -msgstr "" - -#: lib/Translate.php:439 lib/Translate.php:478 -msgid "Error: No locale specified." -msgstr "" - -#: extract.php:36 templates/index.php:43 lib/Application.php:65 -msgid "Extract" -msgstr "" - -#: extract.php:33 -msgid "Extract Translation" -msgstr "" - -#: lib/Translate.php:334 -#, php-format -msgid "Extracting from %s... " -msgstr "" - -#: lib/Translate.php:499 lib/Translate.php:519 lib/Translate.php:540 -#: lib/Translate.php:656 lib/Translate.php:678 lib/Translate.php:741 -msgid "Failed!" -msgstr "" - -#: config/hooks.php.dist:24 -msgid "File doesn't exist ... " -msgstr "" - -#: view.php:222 -msgid "Filter: " -msgstr "" - -#: extract.php:92 make.php:61 reset.php:34 commit.php:35 -msgid "Found applications:" -msgstr "" - -#: extract.php:84 -msgid "Found directories:" -msgstr "" - -#: lib/Babel.php:24 -#, php-format -msgid "Function doesn't exist: %s" -msgstr "" - -#: stats.php:81 view.php:200 view.php:246 view.php:248 -msgid "Fuzzy" -msgstr "" - -#: extract.php:105 make.php:65 -msgid "Generate Compendium ..." -msgstr "" - -#: templates/index.php:44 -msgid "Generate and merge PO files." -msgstr "" - -#: templates/index.php:38 -msgid "Get statistics about translations." -msgstr "" - -#: extract.php:50 lib/Translate.php:77 -msgid "Gettext extension not found!" -msgstr "" - -#: lib/Babel.php:27 -msgid "Hook file doesn't exist" -msgstr "" - -#: extract.php:46 reset.php:24 stats.php:42 commit.php:22 -msgid "Horde translation generator" -msgstr "" - -#: lib/Translate.php:517 -#, php-format -msgid "Initializing module %s..." -msgstr "" - -#: upload.php:37 -msgid "Invalid Translations file. Please submit a valid PO file!" -msgstr "" - -#: stats.php:77 view.php:196 -msgid "Language" -msgstr "" - -#: lib/Babel.php:38 -#, php-format -msgid "Language: %s (%s)" -msgstr "" - -#: lib/Application.php:29 -msgid "Languages" -msgstr "" - -#: extract.php:54 lib/Translate.php:80 -msgid "Loading libraries..." -msgstr "" - -#: stats.php:78 view.php:197 -msgid "Locale" -msgstr "" - -#: view.php:432 -#, php-format -msgid "Locked by %s" -msgstr "" - -#: make.php:36 templates/index.php:49 lib/Application.php:66 -msgid "Make" -msgstr "" - -#: make.php:33 -msgid "Make Translation" -msgstr "" - -#: extract.php:72 lib/Translate.php:98 -msgid "Make sure that you have PEAR installed and in your include path." -msgstr "" - -#: lib/Translate.php:482 -#, php-format -msgid "Merging all %s.po files to the compendium... " -msgstr "" - -#: lib/Translate.php:463 -#, php-format -msgid "Merging locale %s..." -msgstr "" - -#: lib/Translate.php:666 -#, php-format -msgid "Merging the PO file for %s to the compendium..." -msgstr "" - -#: lib/Translate.php:450 -#, php-format -msgid "Merging translation for module %s..." -msgstr "" - -#: view.php:177 -msgid "Meta Informations" -msgstr "" - -#: viewsource.php:25 -msgid "Missing filename!" -msgstr "" - -#: extract.php:37 edit.php:76 make.php:37 upload.php:20 stats.php:33 -#: view.php:155 -msgid "Module" -msgstr "" - -#: lib/Babel.php:40 -#, php-format -msgid "Module: %s" -msgstr "" - -#: lib/Application.php:39 -msgid "Modules" -msgstr "" - -#: lib/Translate_Help.php:221 -#, php-format -msgid "No entry with the id '%s' exists in the original help file." -msgstr "" - -#: lib/Translate.php:127 -msgid "Not all strings will be extracted." -msgstr "" - -#: lib/Translate.php:425 -msgid "Not changed!" -msgstr "" - -#: stats.php:83 view.php:202 -msgid "Obsolete" -msgstr "" - -#: lib/Babel.php:274 -msgid "Please be patient ..." -msgstr "" - -#: upload.php:31 -msgid "Please select module of translations PO file!" -msgstr "" - -#: templates/index.php:61 lib/Application.php:68 -msgid "Reset" -msgstr "" - -#: reset.php:43 -msgid "Reset PO file on " -msgstr "" - -#: reset.php:38 -msgid "Reset PO files ..." -msgstr "" - -#: lib/Translate.php:687 -msgid "Results (including Horde):" -msgstr "" - -#: lib/Translate.php:685 -msgid "Results:" -msgstr "" - -#: edit.php:55 edit.php:80 view.php:442 -msgid "Save" -msgstr "" - -#: view.php:269 -msgid "Search" -msgstr "" - -#: extract.php:80 make.php:56 -#, php-format -msgid "Searching Horde applications in %s" -msgstr "" - -#: lib/Translate.php:107 -msgid "Searching gettext binaries..." -msgstr "" - -#: lib/Translate_Help.php:173 lib/Translate.php:456 lib/Translate.php:564 -#: lib/Translate.php:723 -msgid "Skipped..." -msgstr "" - -#: view.php:190 -msgid "Statistic" -msgstr "" - -#: templates/index.php:37 lib/Application.php:62 -msgid "Statistics" -msgstr "" - -#: stats.php:79 view.php:198 -msgid "Status" -msgstr "" - -#: templates/index.php:62 -msgid "" -"The reset procedure will delete all PO files from the server for all modules " -"and restore from SVN server." -msgstr "" - -#: lib/Translate_Help.php:83 -#, php-format -msgid "There was an error opening the file %s." -msgstr "" - -#: stats.php:80 view.php:199 view.php:235 view.php:237 -msgid "Translated" -msgstr "" - -#: view.php:304 -msgid "Translations" -msgstr "" - -#: upload.php:21 -msgid "Translations File (.PO)" -msgstr "" - -#: stats.php:82 view.php:201 view.php:256 view.php:258 -msgid "Untranslated" -msgstr "" - -#: lib/Translate.php:422 -msgid "Updated!" -msgstr "" - -#: lib/Translate_Help.php:62 lib/Translate_Help.php:180 -#, php-format -msgid "Updating %s help file for %s." -msgstr "" - -#: upload.php:19 upload.php:25 templates/index.php:31 lib/Application.php:61 -msgid "Upload" -msgstr "" - -#: templates/index.php:32 -msgid "Upload new PO files." -msgstr "" - -#: upload.php:18 -msgid "Upload new Translation" -msgstr "" - -#: upload.php:45 -#, php-format -msgid "Upload successful for %s (%s)" -msgstr "" - -#: stats.php:32 view.php:154 templates/index.php:19 -msgid "View" -msgstr "" - -#: lib/Application.php:64 -msgid "View Source" -msgstr "" - -#: stats.php:29 -msgid "View Statistics" -msgstr "" - -#: view.php:151 -msgid "View Translation" -msgstr "" - -#: templates/index.php:20 -msgid "View all translations." -msgstr "" - -#: viewsource.php:39 -#, php-format -msgid "View source: %s" -msgstr "" - -#: lib/Application.php:63 -msgid "View/Edit" -msgstr "" - -#: lib/Translate_Help.php:57 -#, php-format -msgid "Warning: Could not copy %s to %s" -msgstr "" - -#: lib/Translate_Help.php:49 lib/Translate.php:576 -#, php-format -msgid "Warning: Could not create locale directory for locale %s:" -msgstr "" - -#: lib/Translate_Help.php:44 -#, php-format -msgid "Warning: The %s help file for %s doesn't yet exist. Creating a new one." -msgstr "" - -#: lib/Translate_Help.php:67 lib/Translate_Help.php:185 -#, php-format -msgid "Warning: The help file %s didn't start with <?xml" -msgstr "" - -#: lib/Translate_Help.php:35 -#, php-format -msgid "Warning: There doesn't yet exist a help file for %s." -msgstr "" - -#: lib/Translate_Help.php:77 lib/Translate_Help.php:195 -#: lib/Translate_Help.php:201 -#, php-format -msgid "Warning: There was an error opening the file %s." -msgstr "" - -#: lib/Translate.php:126 -msgid "" -"Warning: Your gettext version is too old and does not support PHP natively." -msgstr "" - -#: lib/Translate.php:598 -msgid "Warning: an error has occured:" -msgstr "" - -#: lib/Translate.php:612 -#, php-format -msgid "Warning: the Horde PO file for the locale %s does not exist:" -msgstr "" - -#: lib/Babel.php:212 -msgid "_Extract" -msgstr "" - -#: lib/Babel.php:195 -msgid "_General" -msgstr "" - -#: lib/Babel.php:218 -msgid "_Make" -msgstr "" - -#: lib/Babel.php:206 -msgid "_Stats" -msgstr "" - -#: lib/Babel.php:224 -msgid "_Upload" -msgstr "" - -#: lib/Babel.php:200 -msgid "_View" -msgstr "" diff --git a/babel/locale/fr/LC_MESSAGES/babel.mo b/babel/locale/fr/LC_MESSAGES/babel.mo deleted file mode 100644 index e93d8fd23a0b7572a0e9868f7e03371c02a0fc39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157237 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≫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 1);\n" - -#: lib/Translate.php:257 lib/Translate.php:276 -#, php-format -msgid "%s is not writable." -msgstr "%s n'est pas accessible en écriture." - -#: extract.php:65 lib/Translate.php:94 lib/Translate.php:117 -#, php-format -msgid "%s not found." -msgstr "%s non trouvé." - -#: lib/Translate.php:428 -#, php-format -msgid "%s not found. Run 'Extract' first." -msgstr "%s non trouvé. Veuillez faire une 'Extraction'." - -#: view.php:301 -#, php-format -msgid "%s to %s of %s" -msgstr "%s à %s de %s" - -#: lib/Translate.php:302 -#, php-format -msgid "" -" tag not closed in file %s.\n" -"Opening tag found in line %d." -msgstr "" -"La balise n'est pas fermé correctement dans le fichier %s. Balise " -"d'ouverture trouvé à la ligne %d." - -#: viewsource.php:30 -#, php-format -msgid "Access denied to %s" -msgstr "Accès refusé à %s" - -#: lib/base.php:112 lib/base.php:116 -#, php-format -msgid "Access forbidden to '%s'." -msgstr "Accès refusé à '%s'." - -#: view.php:223 view.php:225 -msgid "All" -msgstr "Tout" - -#: lib/Translation.php:53 lib/Translation.php:135 -msgid "All Applications" -msgstr "Toutes les applications" - -#: templates/index.php:50 -msgid "Build binary MO files from the specified PO files." -msgstr "Construire les fichiers binaire MO à partir des fichiers PO spécifié." - -#: lib/Translate.php:467 -#, php-format -msgid "Building MO files for module %s..." -msgstr "Génération des fichiers MO pour le module %s ..." - -#: lib/Translate.php:479 -#, php-format -msgid "Building locale %s..." -msgstr "Généré locale %s ..." - -#: lib/Translation.php:292 -#, php-format -msgid "Can take up to %d minutes !" -msgstr "Peut prendre jusqu'à %d minutes !" - -#: lib/Translation.php:286 -#, php-format -msgid "Can take up to %d seconds !" -msgstr "Peut prendre jusqu'à %d secondes !" - -#: lib/Translation.php:290 -msgid "Can take up to 1 minute !" -msgstr "Peut prendre jusqu'à 1 minute !" - -#: view.php:442 -msgid "Cancel" -msgstr "Annuler" - -#: lib/Translate.php:626 -#, php-format -msgid "Cleaning up PO files for module %s..." -msgstr "Nettoyage des fichiers PO pour le module %s ..." - -#: lib/Translate.php:638 -#, php-format -msgid "Cleaning up locale %s..." -msgstr "Netoyage de la locale %s ..." - -#: commit.php:42 templates/index.php:55 lib/api.php:66 -msgid "Commit" -msgstr "Validez" - -#: commit.php:36 -msgid "Commit PO files ..." -msgstr "Validez les fichier PO ..." - -#: templates/index.php:56 -msgid "Commit translations to the SVN server." -msgstr "Validez (commit) les traductions sur le serveur SVN." - -#: extract.php:114 lib/Translate.php:374 lib/Translate.php:405 -#: lib/Translate.php:446 lib/Translate.php:536 lib/Translate.php:584 -#: lib/Translate.php:646 -msgid "Done!" -msgstr "Terminé!" - -#: templates/index.php:25 lib/api.php:59 -msgid "Download" -msgstr "Télécharger" - -#: download.php:14 -msgid "Download File" -msgstr "Télécharger Fichier" - -#: templates/index.php:26 -msgid "Download all current PO files." -msgstr "Télécharger tous les fichiers PO." - -#: edit.php:78 -msgid "Edit" -msgstr "Modifier" - -#: view.php:164 -msgid "Edit Header" -msgstr "Modifier Entête" - -#: view.php:229 -msgid "Edit Mode" -msgstr "Mode Édition" - -#: edit.php:52 view.php:438 -msgid "Edit Translation" -msgstr "Modifier Traduction" - -#: lib/Translate.php:347 lib/Translate.php:386 -msgid "Error: No locale specified." -msgstr "Erreur: Il n'y a pas de locale de spécifié." - -#: extract.php:36 templates/index.php:43 lib/api.php:64 -msgid "Extract" -msgstr "Extraire" - -#: extract.php:33 -msgid "Extract Translation" -msgstr "Extraire Traduction" - -#: lib/Translate.php:242 -#, php-format -msgid "Extracting from %s... " -msgstr "Extraction à partir de %s ..." - -#: lib/Translate.php:407 lib/Translate.php:427 lib/Translate.php:448 -#: lib/Translate.php:564 lib/Translate.php:586 lib/Translate.php:649 -msgid "Failed!" -msgstr "Échoué!" - -#: config/hooks.php:24 -msgid "File doesn't exist ... " -msgstr "Fichier non existant ..." - -#: view.php:220 -msgid "Filter: " -msgstr "Filtres: " - -#: commit.php:32 make.php:61 reset.php:34 extract.php:92 -msgid "Found applications:" -msgstr "Applications Trouvée :" - -#: lib/Translation.php:24 -#, php-format -msgid "Function doesn't exist: %s" -msgstr "Fonction non-existante: %s" - -#: view.php:198 view.php:244 view.php:246 stats.php:81 -msgid "Fuzzy" -msgstr "Floue" - -#: make.php:65 extract.php:105 -msgid "Generate Compendium ..." -msgstr "Génération du Compendium ..." - -#: templates/index.php:44 -msgid "Generate and merge PO files." -msgstr "Générer et fusionner les fichier PO." - -#: templates/index.php:38 -msgid "Get statistics about translations." -msgstr "Obtenir les statistiques concernant les traductions." - -#: extract.php:50 lib/Translate.php:80 -msgid "Gettext extension not found!" -msgstr "Extension Gettext non trouvé!" - -#: lib/Translation.php:27 -msgid "Hook file doesn't exist" -msgstr "Fichier Hook non existant" - -#: commit.php:19 reset.php:24 stats.php:42 extract.php:46 -msgid "Horde translation generator" -msgstr "Générateur de traduction Horde" - -#: lib/Translate.php:425 -#, php-format -msgid "Initializing module %s..." -msgstr "Initialisation du module %s ..." - -#: upload.php:37 -msgid "Invalid Translations file. Please submit a valid PO file!" -msgstr "" -"Fichier de traductions invalide. Veuillez soumettre un fichier PO valide !" - -#: view.php:194 stats.php:77 -msgid "Language" -msgstr "Langue" - -#: lib/Translation.php:38 -#, php-format -msgid "Language: %s (%s)" -msgstr "Langue: %s (%s)" - -#: lib/api.php:28 -msgid "Languages" -msgstr "Langues" - -#: extract.php:54 lib/Translate.php:83 -msgid "Loading libraries..." -msgstr "Chargement des librairies ..." - -#: view.php:195 stats.php:78 -msgid "Locale" -msgstr "Locale" - -#: view.php:430 -#, php-format -msgid "Locked by %s" -msgstr "Verouillé par %s" - -#: make.php:36 templates/index.php:49 lib/api.php:65 -msgid "Make" -msgstr "Générer" - -#: make.php:33 -msgid "Make Translation" -msgstr "Générer la Traduction" - -#: lib/Translate.php:101 -msgid "Make sure that you have PEAR installed and in your include path." -msgstr "" -"Veuillez vérifier que vous avez installé PEAR et qu'il sont include dans le " -"chemin d'accès (include path)." - -#: lib/Translate.php:390 -#, php-format -msgid "Merging all %s.po files to the compendium... " -msgstr "Fusionner tous les fichiers %s.po vers le compendium..." - -#: lib/Translate.php:371 -#, php-format -msgid "Merging locale %s..." -msgstr "Fusion de la locale %s ..." - -#: lib/Translate.php:574 -#, php-format -msgid "Merging the PO file for %s to the compendium..." -msgstr "Fusionner tous les fichiers PO pour %s vers le compendium..." - -#: lib/Translate.php:358 -#, php-format -msgid "Merging translation for module %s..." -msgstr "Fusion de la traduction pour le module %s ..." - -#: view.php:175 -msgid "Meta Informations" -msgstr "Informations Meta" - -#: viewsource.php:25 -msgid "Missing filename!" -msgstr "Nom de fichier manquant!" - -#: edit.php:79 make.php:37 view.php:153 upload.php:20 stats.php:33 -#: extract.php:37 -msgid "Module" -msgstr "Module" - -#: lib/Translation.php:40 -#, php-format -msgid "Module: %s" -msgstr "Module: %s" - -#: lib/api.php:38 -msgid "Modules" -msgstr "Modules" - -#: lib/Translate.php:130 -msgid "Not all strings will be extracted." -msgstr "Les chaînes de caractères n'ont pas toutes été extraite." - -#: lib/Translate.php:333 -msgid "Not changed!" -msgstr "Non modifié!" - -#: view.php:200 stats.php:83 -msgid "Obsolete" -msgstr "Obsolète" - -#: lib/Translation.php:282 -msgid "Please be patient ..." -msgstr "Veuillez patienter..." - -#: upload.php:31 -msgid "Please select module of translations PO file!" -msgstr "Veuillez sélectionner le module pour le fichier PO de traduction." - -#: templates/index.php:61 lib/api.php:67 -msgid "Reset" -msgstr "Réinitialiser" - -#: reset.php:43 -msgid "Reset PO file on " -msgstr "Ré-initialisation du fichier PO pour " - -#: reset.php:38 -msgid "Reset PO files ..." -msgstr "Ré-initialisation des fichiers PO ..." - -#: lib/Translate.php:595 -msgid "Results (including Horde):" -msgstr "Résultats (incluant Horde):" - -#: lib/Translate.php:593 -msgid "Results:" -msgstr "Résultats:" - -#: edit.php:55 edit.php:83 view.php:440 -msgid "Save" -msgstr "Enregistrer" - -#: view.php:267 -msgid "Search" -msgstr "Recherche" - -#: lib/Translate.php:110 -msgid "Searching gettext binaries..." -msgstr "Recherche des exécutables pour gettext ..." - -#: lib/Translate.php:364 lib/Translate.php:472 lib/Translate.php:631 -msgid "Skipped..." -msgstr "Ignoré..." - -#: view.php:188 -msgid "Statistic" -msgstr "Statistique" - -#: templates/index.php:37 lib/api.php:61 -msgid "Statistics" -msgstr "Statistiques" - -#: view.php:196 stats.php:79 -msgid "Status" -msgstr "Statut" - -#: templates/index.php:62 -msgid "" -"The reset procedure will delete all PO files from the server for all modules " -"and restore from SVN server." -msgstr "" -"La procédure de ré-initialisation effacera tous les fichiers PO du serveur " -"et les restaurera à partir du serveur SVN." - -#: view.php:197 view.php:233 view.php:235 stats.php:80 -msgid "Translated" -msgstr "Traduit" - -#: view.php:302 -msgid "Translations" -msgstr "Traductions" - -#: upload.php:21 -msgid "Translations File (.PO)" -msgstr "Fichier de Traduction (.PO)" - -#: view.php:199 view.php:254 view.php:256 stats.php:82 -msgid "Untranslated" -msgstr "Non Traduit" - -#: lib/Translate.php:330 -msgid "Updated!" -msgstr "Mis à jour!" - -#: upload.php:19 upload.php:25 templates/index.php:31 lib/api.php:60 -msgid "Upload" -msgstr "Envoi" - -#: templates/index.php:32 -msgid "Upload new PO files." -msgstr "Envoyer nouveaux fichiers PO." - -#: upload.php:18 -msgid "Upload new Translation" -msgstr "Envoi une nouvelle Traduction" - -#: upload.php:45 -#, php-format -msgid "Upload successful for %s (%s)" -msgstr "Transfert de fichier réussi pour %s (%s)" - -#: view.php:152 stats.php:32 templates/index.php:19 -msgid "View" -msgstr "Voir" - -#: lib/api.php:63 -msgid "View Source" -msgstr "Visionner Source" - -#: stats.php:29 -msgid "View Statistics" -msgstr "Voir Statistiques" - -#: view.php:149 -msgid "View Translation" -msgstr "Voir Traduction" - -#: templates/index.php:20 -msgid "View all translations." -msgstr "Visionner toutes les traductions." - -#: viewsource.php:39 -#, php-format -msgid "View source: %s" -msgstr "Voir source: %s" - -#: lib/api.php:62 -msgid "View/Edit" -msgstr "Visionner/Modifier" - -#: lib/Translate.php:484 -#, php-format -msgid "Warning: Could not create locale directory for locale %s:" -msgstr "Avertissement: Impossible de créer le dossier pour le locale %s :" - -#: lib/Translate.php:129 -msgid "" -"Warning: Your gettext version is too old and does not support PHP natively." -msgstr "" -"Avertissement: Votre version de gettext est trop ancienne et ne supporte pas " -"PHP nativement." - -#: lib/Translate.php:506 -msgid "Warning: an error has occured:" -msgstr "Avertissement: Une erreur s'est produite:" - -#: lib/Translate.php:520 -#, php-format -msgid "Warning: the Horde PO file for the locale %s does not exist:" -msgstr "Avertissement: le fichier PO de Horde pour le locale %s n'existe pas:" - -#: lib/Translation.php:214 -msgid "_Extract" -msgstr "_Extraire" - -#: lib/Translation.php:197 -msgid "_General" -msgstr "_Général" - -#: lib/Translation.php:220 -msgid "_Make" -msgstr "Gé_nérer" - -#: lib/Translation.php:208 -msgid "_Stats" -msgstr "_Stats" - -#: lib/Translation.php:226 -msgid "_Upload" -msgstr "En_voi" - -#: lib/Translation.php:202 -msgid "_View" -msgstr "_Visionner" diff --git a/babel/make.php b/babel/make.php deleted file mode 100644 index 151dad8b5..000000000 --- a/babel/make.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package Babel - */ - -set_time_limit(0); - -@define('BABEL_BASE', dirname(__FILE__)) ; -require_once BABEL_BASE . '/lib/base.php'; - -if ($app) { - /* Render the page. */ - Babel::RB_init(); -} - -require BABEL_TEMPLATES . '/common-header.inc'; - -if ($app) { - Babel::RB_start(30); -} - -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -$vars = &Horde_Variables::getDefaultVariables(); - -/* Create upload form */ -$form = new Horde_Form($vars, _("Make Translation"), 'make'); - -if (!$app) { - $form->setButtons(_("Make")); - $form->addVariable(_("Module"), 'module', 'enum', true, false, null, array(Babel::listApps(true), true)); - $form->addVariable('', '', 'spacer', true); - - $renderer_params = array(); - $renderer = new Horde_Form_Renderer($renderer_params); - $renderer->setAttrColumnWidth('20%'); - - $form->renderActive($renderer, $vars, Horde::selfURL(), 'post'); -} else { - - if ($app != 'ALL') { - $module = $app; - } - - Translate::sanity_check(); - - /* Searching applications */ - Translate::check_binaries(); - - Translate_Display::info(sprintf(_("Searching Horde applications in %s"), realpath(HORDE_BASE))); - $dirs = Translate::search_applications(); - - $apps = Translate::strip_horde($dirs); - $apps[0] = 'horde'; - Translate_Display::info(_("Found applications:")); - Translate_Display::info(wordwrap(implode(', ', $apps)), false); - Translate_Display::info(); - - Translate_Display::header(_("Generate Compendium ...")); - Translate::compendium(); - Translate_Display::info(); - - Translate::cleanup(true); - Translate_Display::info(); - Translate::make(); - - Babel::RB_close(); -} - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/reset.php b/babel/reset.php deleted file mode 100644 index 5f1a0927c..000000000 --- a/babel/reset.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @package Babel - */ - -@define('BABEL_BASE', dirname(__FILE__)) ; -require_once BABEL_BASE . '/lib/base.php'; - -Babel::RB_init(); - -/* Render the page. */ -require BABEL_TEMPLATES . '/common-header.inc'; - -Babel::RB_start(15); - -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -Translate_Display::header(_("Horde translation generator")); - -Translate_Display::info(sprintf('Searching Horde applications in %s', realpath(HORDE_BASE))); - -Translate::check_binaries(); - -$dirs = Translate::search_applications(); - -$apps = Translate::strip_horde($dirs); -$apps[0] = 'horde'; -Translate_Display::info(_("Found applications:")); -Translate_Display::info(wordwrap(implode(', ', $apps)), false); -Translate_Display::info(); - -Translate_Display::header(_("Reset PO files ...")); -foreach($dirs as $d => $dir) { - $dir = realpath($dir); - $po = $dir . '/po/' . $lang . '.po'; - - Translate_Display::info(_("Reset PO file on ") . $po); - Babel::callHook('reset', $po); - -} - -Translate_Display::info(); -Translate::cleanup(true); - -Babel::RB_close(); - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/stats.php b/babel/stats.php deleted file mode 100644 index b97664028..000000000 --- a/babel/stats.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @package Babel - */ - -@define('BABEL_BASE', dirname(__FILE__)) ; -require_once BABEL_BASE . '/lib/base.php'; - -if ($app) { - /* Render the page. */ - Babel::RB_init(); -} -require BABEL_TEMPLATES . '/common-header.inc'; - -if ($app) { - Babel::RB_start(30); -} -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -$vars = &Horde_Variables::getDefaultVariables(); - -/* Create upload form */ -$form = new Horde_Form($vars, _("View Statistics"), 'stats'); - -if (!$app) { - $form->setButtons(_("View")); - $form->addVariable(_("Module"), 'module', 'enum', true, false, null, array(Babel::listApps(true), true)); - $form->addVariable('', '', 'spacer', true); - - $renderer_params = array(); - $renderer = new Horde_Form_Renderer($renderer_params); - $renderer->setAttrColumnWidth('20%'); - - $form->renderActive($renderer, $vars, Horde::selfURL(), 'post'); -} else { - Translate_Display::header(_("Horde translation generator")); - - $dirs = Translate::search_applications(); - $apps = Translate::strip_horde($dirs); - $apps[0] = 'horde'; - Translate_Display::info(); - - foreach($dirs as $d => $dir) { - $dir = realpath($dir); - $pofile = $dir . '/po/' . $lang . '.po'; - - if (!@file_exists($pofile)) { - continue; - } - - $_app = str_replace(realpath(HORDE_BASE), '', $dir); - $_app = str_replace('/', '', $_app); - if (empty($_app)) { - $_app = 'horde'; - } - - if ($app != 'ALL' && $app != $_app) { - continue; - } - - if (!Babel::hasPermission("module:$_app")) { - continue; - } - - Translate_Display::header($_app); - - $report = Translate::stats($_app); - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - $i = 0; - $j = 0; - $line = 0; - $last_key = null; - foreach ($report as $key => $value) { - - if (!Babel::hasPermission("language:$key")) { - continue; - } - - if ($key == $_SESSION['babel']['language']) { - echo "\n"; - } else { - echo "\n"; - } - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\t"; - $last_key = $key; - } - - echo '
' . _("Language") . '' . _("Locale") . '' . _("Status") . '' . _("Translated") . '' . _("Fuzzy") . '' . _("Untranslated") . '' . _("Obsolete") . '
" . Horde_Nls::$config['languages'][$key] . "" . Horde::link(Horde_Util::addParameter(Horde::url('view.php'), array('display_language' => $key, 'module' => $_app))) . $key . '' . "" . Translate_Display::create_bargraph($value[2], $value[0]) . "" . $value[2] . "" . $value [3] . "" . $value[4] . "" . $value[5] . "
'; - - Translate_Display::info(); - } - - Babel::RB_close(); -} - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/templates/common-header.inc b/babel/templates/common-header.inc deleted file mode 100644 index 3a4bd4491..000000000 --- a/babel/templates/common-header.inc +++ /dev/null @@ -1,25 +0,0 @@ -getCharset()); - header('Vary: Accept-Language'); -} -?> - -' : '' ?> - -get('name'); -if (!empty($title)) { - $page_title .= ' :: ' . $title; -} - -Horde::outputMetaTags(); -Horde::includeScriptFiles(); - -?> -<?php echo $page_title ?> - - - - diff --git a/babel/templates/index.php b/babel/templates/index.php deleted file mode 100644 index c6bd159ac..000000000 --- a/babel/templates/index.php +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - _("View"), - 'text' => _("View all translations."), - 'url' => Horde::url('view.php') -); - -$cmds['download'] = array( - 'desc' => _("Download"), - 'text' => _("Download all current PO files."), - 'url' => Horde::url('download.php') -); - -$cmds['upload'] = array( - 'desc' => _("Upload"), - 'text' => _("Upload new PO files."), - 'url' => Horde::url('upload.php') -); - -$cmds['stats'] = array( - 'desc' => _("Statistics"), - 'text' => _("Get statistics about translations."), - 'url' => Horde::url('stats.php') -); - -$cmds['extract'] = array( - 'desc' => _("Extract"), - 'text' => _("Generate and merge PO files."), - 'url' => Horde::url('extract.php') -); - -$cmds['make'] = array( - 'desc' => _("Make"), - 'text' => _("Build binary MO files from the specified PO files."), - 'url' => Horde::url('make.php') -); - -$cmds['commit'] = array( - 'desc' => _("Commit"), - 'text' => _("Commit translations to the SVN server."), - 'url' => Horde::url('commit.php') -); - -$cmds['reset'] = array( - 'desc' => _("Reset"), - 'text' => _("The reset procedure will delete all PO files from the server for all modules and restore from SVN server."), - 'url' => Horde::url('reset.php') -); - - -$i = 0; - -foreach($cmds as $cmdid => $cmd) { - if (Babel::hasPermission($cmdid)) { - echo ''; - echo ''; - echo ''; - echo ''; - } -} -?> -
-

- Command -

-
-

- Description -

-
' . $cmd['text'] . '
diff --git a/babel/templates/layout.html b/babel/templates/layout.html deleted file mode 100644 index ec84ebc8e..000000000 --- a/babel/templates/layout.html +++ /dev/null @@ -1,14 +0,0 @@ - -
- - - - - -
-
diff --git a/babel/themes/graphics/babel.png b/babel/themes/graphics/babel.png deleted file mode 100644 index 8e4f3923d96b09808453e7943f157c389e8f243d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 702 zcmV;v0zv(WP)pC+rKfFY23;eBi-Sb;evdTjC z%XD6ykfm)gl2;n4YR=iet+ZEjwQr#88on+TX(D1GQwa(Z!}1u3=uUUg4;CM0q)r3+ zCg`Z;ke5rLh|H9!xZ8_^_Kbn1@0K59jfK!&32ho^E@kLuEZ)`Tu-&sJ{penb1`Yt!dC02aglbWd*~) zc@jfxZ;IlCy%U-0 zLp%+$Q?@USZ93=Gve|LQX(@^@D5HH1Z(kgz{81XCH9O(y7O2<_-D&W7E4IiykMlKoAoxBDb zGnA1y)HVkDkppxp7l8p`JVO|H7y#|Z>3QZqsxpz)^1DR~ z#q)WtLo2m@P^5yp0>eruH5s5wF&%ku(&;0_G0+n~Zfzzj_xO#lD@07*qoM6N<$f*8+7V*mgE diff --git a/babel/themes/graphics/checked.gif b/babel/themes/graphics/checked.gif deleted file mode 100644 index 56cacd3b5a527760fe9db83afe30a399c0c2e36a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75 zcmZ?wbhEHbcLq zVfpg4opl*McW-=su4DCv&FeSpT(fptQ&r0QTg&dxnHCh_-PS(g)7|BpHf{gXT3%mM zeralem5J((HNBgcw!D9|ZRz4=>gqb@7qs1PsNNYAoD>t3pI>-z#q{rcwm&&N|6N>3_BDG}6)-FIwBxt*p$)YHDA+cw3Sc_V@M1@6Wfi`8(Iv zxA?L%{cp*?bZq4mRmJ!BcTMQ+d3<5c+-coROiWKsPknH5@?9Mnd1;aJ4Rvk~2KUa* z^9zigHhszR6|4W;pa1{G;uoh{W^dgJj5Yu4jOjqCuO!GX`2S!6472BbsRFv}sHcl# zh(vhu3s+_yfl~~pcpEu2TANogaj$Ub+uvg|;ZfH0HjWOjqitKiecN=y@od7>u>MY; z?coJ2Qd$qPV`Eh2EDg=(7X0w~f`?&W@$@xi&z>=JZ`rw%<+aJ{sTpA*tS_CVT4Gn4*_1RDRR-2Qy%uL=t8^}JdMwOZEGb!aGssu!=i(?4 z)exV#M_yG)Y8{bP0l+XkKIQizu diff --git a/babel/themes/graphics/down.png b/babel/themes/graphics/down.png deleted file mode 100644 index b6892f0b9a581cad6021e5ea624cca5a86a85e5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 503 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMflK`I(SDuppqIs{mGG2>hzqonx z=H^@fwm$wZko&=^@fBCr2cMQ}#^qPIVy^f%TvBcSzhv23j@(}=<Pn*9Y*n+9Q)pHfA%kA`Txv?&;1IQq;L3@ z(sI~p%72f#%Uosu1$;J`$IOy!{IA>fXVsoZ>fQhE-G4Z3_owyezZdTOKVj2D|M~yT z3eFxmdR#p9=7<0Pd$zn|O?k)Qe^##Le{s_sw`o6Hj{ZM>;fZhmhZ*xXzIpSeXVUy{ z-@duzZMyyHk9FJotD=Jh@~12nhH)5S4FVrudS zH)ftA92Eweyqjk9`OG<%z{pq5npc~j&nzgbpSq!8#nRTjv$xM^=``zCKf)8|Y*r~* zYAvlDy<%a|vNdkcnyQ$h&KX3P>^ySyhlI&lforR@G_xXhE9`WR@@tK}CVDfG&*_lP j3cb=t>PPigFfar>x4-}3_N@az7ch9b`njxgN@xNAV3r>e diff --git a/babel/themes/graphics/edit.png b/babel/themes/graphics/edit.png deleted file mode 100644 index 3a082d3ec76902e38045a736f7f6c32a20e4b010..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 795 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 diff --git a/babel/themes/graphics/make.png b/babel/themes/graphics/make.png deleted file mode 100644 index 9fc79ccbf1cd9061947e09b17d457cec29e9efcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 602 zcmV-g0;T17#4y~d#5-r0Z3UU{;3tF^@YFmpIQM;gpn`#%)qD3jjkdm}$k)t98nFLmL zQ$x_yCZ%M?yiEB!&gH-V=lqwaVU&hpW>NIP184I-hx2|M(bm?+|4+)c@z@>PG3+>CCy_@3Xt#2H^IZsRL9L-m!X}UZKP%S9h5xNy(+5uY8Cs$D9avs{I z!w=0O_0#10n!&paoRsi6Huxdn{n+s`Oi@1^UdA6<~kY#-3qC5xbTJ;5YW0|0WKr1;?PHEiEps7tYMpay$&L#mM!*lD?~T!e-dzgOwzL;xi%3H z>jBZ_(Kn_M$$BL!n^!4|*q|adAZd6WA=*JaqAV000Y@KeBo{aErBf?#92?WL=}YE# z`&HxAxPj<_eF>AsPl{cg1~1>IkyfF8iLUG7c`m3Dp+|SJ$dTbJqtm~*H=gC;yEKVJ zqKfJ@N?AdbuwC@5P9Qx{5?jxgLqO$rA$I=}_`Y975covl);SCV3`5@%RKl?mqAd8E o34)+3*bX;{?fIwgTnSg^H+rWlT`OglC;$Ke07*qoM6N<$f>|~Zod5s; diff --git a/babel/themes/graphics/sample.png b/babel/themes/graphics/sample.png deleted file mode 100644 index 21cfa00961c21f6fc9c543006e02092dc3ac0986..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!M1W6-E0AVTWMF7vD1Kku^1Ws4 z|F!4-pS$+|+N7r7GN2S=NswPKgTu2MX+Vyxr;B4q#jUw#4stOla4=tp$@>5QIH%{M zysgb2+N|y|O}OhY@6b8#P5wt>%H>yemGO6PsZV-${OXd`od46Ai})GN#Hy}x0@>*4 L>gTe~DWM4fYcV@f diff --git a/babel/themes/graphics/unchecked.gif b/babel/themes/graphics/unchecked.gif deleted file mode 100644 index bb87f1c5ec3b4f018fd6eac73abaa606c4a05da3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 zcmZ?wbhEHb7)VyD;Km5V6~ Rt5BYi_jy98XAlE}H2|a)6p8=< diff --git a/babel/themes/graphics/up.png b/babel/themes/graphics/up.png deleted file mode 100644 index 35acc28bafd2009756ae1fd4cb74d1bf86ce2c5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 517 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf+W?;s*NnnGr|vI~-CzFx{ijg* zS*hX!TgiWskUeU-=grG**mr-+sG75J^Y*wo-<8tO>v#T?Ed5~F@vCFokCx4Uq)Of_ zJo3wH?SJ=-#j*h_8FT*#C0!3*{{Q>Wzjr_V51sj=ZOYn=${Ej|J)3asU&rzPrylJT)JXb3#n<$CbE|D5? zR zG(3_x`~KO}l=@c|vx~Ju06<6y30&6$@d<fVn@=ig zq40?R7XYOUZp#Cu1e^^ zX9%Q3)2d;6dkvYpd;*FXG@*?`&9%iM1l{X7innFU|AMk zJu!%@S1&=z5J8~e&y6iOE&C;)rj+UFPo}%EcJGCdg(L9kl+1Gz^lnDE|(+j3!9 z0)$BTK7&sz84-*YQE;z&(>I(hBNg^%an=$gctqwl~LHe#Jo6rx3}F5X2ynSg1w zU^^asPoUBCuv@DO%KWMtdDFNsJvaGwpfEVH2~E)uh5;I)j$|SM|9BaVU>AgNSe6gV z@!?Yr+p;O6{*HQNtbL{*`Sb5HCr*ynb}Oadi`iSb+|So7%Pa%H-@&2X U5KR{PhX4Qo07*qoM6N<$f>|`R>Hq)$ diff --git a/babel/themes/graphics/view.png b/babel/themes/graphics/view.png deleted file mode 100644 index 8f29061da5707eba1584a040005ba9efd17cd948..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1348 zcmV-K1-tr*P)!<$y;( zfI6V&szWqqS4Q{$$sH7L30Tp?>v0!^9bk^=M{o)&pL~6$KGtAoUA&M7o8v{jH#VN@ zn7eH#w!GEJ>%#EVKQ75~%=e)7ce$l><>;uNO%UQrf8SodM#+qcjxWnkm*@*F+z`|S zmiUYpjYp}rdt6=snKK1~dV`JuP@8mBYg=0_@5+gb#EFuimPd+*gDqozs*v$Z(qtHK z^ci$(jFMc`?&`y4)K+a_WegQYeV=f)aB7xLSbKq4(fb4~pOTZOr`A7xUU$&|6YFI~ z>O41WhHJhhqrHEi&t)QAlQKNOaRzcRL7Cc2K%Q=3j^Bx$4Yv) zNB@>mP_cHlyy8?P<{>RR9BcsZgNqjH7Y)$q+!-)*Ga@yaoWGIbDQRVj)kOwB_E(Vi zyz#afCzHTD3f~v>0;KP9yF?QT0E_7dM;s7N}SN~rv(4^f?*QfoG@ z7A+c}UeRdH&O3J%S4&K+-y`g;a}?ur4AvF_3t$1@t{8VTZ9}-QFvJYP$?i=s9s&rP z((#D~V*+um5OH#6#&~EV+jD9%@dhsfd072EPw!n7dZZ&8Kgf~pfuQW(tj6Hydia!Ss* zn@)5$_IU|j;;T67C42QL_pnk=l?RFYuO2LbW<#3f z^eXASdhLVGmMXb*mkrtDiKh%NT0vXh6EM1NbW@Ep-HAt)6y33`?qX`mPNG;*gu-Vl z_8-R@03+%p#!F2dd!VI4JNoWxCkWZo4(+Tbom?AfUB*vuv?AK4B&wd)H$(&=7SrujCyyKkfNp_x-ye&FF+5AdukB9F zg@d%6(0!Zp3kGj`m;4uCW>k(77kF$_K((6F4U+Ryt4qHOSqng2a{Q4!K}a~=rG$}# zGa2vFwnLP+XS@Ia*T9u9+P-=yo$gqiOFCSimqhsiBU?f{QbNpGN5H~6v>g!5CgE)x zznB5lv%;D~vj#}yP%Wd3FvTvOXW+fsH0Zl!EB`O!=lU1N>xA1DS#j(D0000 - * @package Babel - */ - -@define('BABEL_BASE', dirname(__FILE__)) ; -require_once BABEL_BASE . '/lib/base.php'; - -$vars = &Horde_Variables::getDefaultVariables(); - -/* Create upload form */ -$form = new Horde_Form($vars, _("Upload new Translation"), 'upload'); -$form->setButtons(_("Upload")); -$form->addVariable(_("Module"), 'module', 'enum', true, false, null, array(Babel::listApps(true), true)); -$form->addVariable(_("Translations File (.PO)"), 'po_file', 'file', true, false); -$form->addVariable('', '', 'spacer', true); - -/* Validate form if submitted */ -if (Horde_Util::getFormData('submitbutton') == _("Upload")) { - if ($form->validate($vars, false)) { - $form->getInfo($vars, $form_values); - - $po_module = @$form_values['module']; - if (empty($po_module)) { - $notification->push(_("Please select module of translations PO file!"), 'horde.error'); - } else { - $po_file_path = @$form_values['po_file']['file']; - $po_file_name = @$form_values['po_file']['name']; - $po_file_size = @$form_values['po_file']['size']; - if (empty($po_file_path) || substr($po_file_name, -3) != '.po' || $po_file_size <= 0) { - $notification->push(_("Invalid Translations file. Please submit a valid PO file!"), 'horde.error'); - } else { - if ($po_module == 'horde') { - $mod = ''; - } else { - $mod = $po_module; - } - - $notification->push(sprintf(_("Upload successful for %s (%s)"), $po_module, $lang), 'horde.success'); - $cmd = "cp $po_file_path " . HORDE_BASE . "/$mod/po/$lang.po"; - system($cmd); - - // Redirect to page URL - Horde::url('upload.php')->redirect(); - } - } - } -} - -/* Render upload page */ -require BABEL_TEMPLATES . '/common-header.inc'; -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -$renderer_params = array(); -$renderer = new Horde_Form_Renderer($renderer_params); -$renderer->setAttrColumnWidth('20%'); - -$form->renderActive($renderer, $vars, Horde::selfURL(), 'post'); - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/view.php b/babel/view.php deleted file mode 100644 index 8d976408c..000000000 --- a/babel/view.php +++ /dev/null @@ -1,504 +0,0 @@ - - * @package Babel - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -require_once 'Horde/Lock.php'; - -$meta_params = array( - "Project-Id-Version" => @$_SESSION['babel']['language'], - "Report-Msgid-Bugs-To" => "support@scopserv.com", - "POT-Creation-Date" => "", - "PO-Revision-Date" => "", - "Last-Translator" => "", - "Language-Team" => "", - "MIME-Version" => "1.0", - "Content-Type" => "text/plain; charset=utf-8", - "Content-Transfer-Encoding" => "8bit", - "Plural-Forms" => "nplurals=2; plural=(n > 1);"); - -$app = Horde_Util::getFormData('module'); -$editmode = Horde_Util::getFormData('editmode', 0); -$cstring = Horde_Util::getFormData('cstring'); -$page = Horde_Util::getFormData('page', 0); -$filter = Horde_Util::getFormData('filter'); -$search = Horde_Util::getFormData('search'); - -if ($app) { - /* Render the page. */ - Babel::RB_init(); -} - -/* Render the page. */ -require BABEL_TEMPLATES . '/common-header.inc'; - -if ($app) { - if ($editmode) { - Babel::RB_start(10); - } else { - Babel::RB_start(60); - } -} - -echo $template->fetch(BABEL_TEMPLATES . '/layout.html'); - -$app = Horde_Util::getFormData('module'); -$show = 'edit'; -$vars = Horde_Variables::getDefaultVariables(); - -if ($app) { - $napp = ($app == 'horde') ? '' : $app; - $pofile = HORDE_BASE . '/' . $napp . '/po/' . $lang . '.po'; - $po = new File_Gettext_PO(); - $po->load($pofile); - - // Set Scope - $lockscope = sprintf("babel-%s-%s", $app, $lang); - - // Initialize Horde_Lock class - $locks = $injector->getInstance('Horde_Lock'); - -// $curlocks = $locks->getLocks($lockscope); -// var_dump($curlocks); -} - -// - -$f_cancel = Horde_Util::getFormData('cancel'); -$f_save = Horde_Util::getFormData('submit'); - -if (($f_save || $f_cancel) && $cstring) { - if ($curlock = $locks->getLocks(md5($cstring), $lockscope)) { - foreach($curlock as $lid => $linfo) { - if ($linfo['lock_scope'] == md5($cstring)) { - $locks->clearLock($lid); - } - } - } -} - -if ($f_save && $cstring) { - - $decstr = $po->encstr[$cstring]; - $msgstr = Horde_Util::getFormData('msgstr'); - $comments = trim($po->comments[$decstr]); - - $phpformat = Horde_Util::getFormData('phpformat'); - $fuzzy = Horde_Util::getFormData('fuzzy'); - - $status = $po->status[$decstr]; - foreach($status as $k => $v) { - if ($v == 'untranslated' && !empty($msgstr)) { - unset($status[$k]); - } - - if ($v == 'php-format' && !$phpformat) { - unset($status[$k]); - } - - if ($v == 'fuzzy' && !$fuzzy) { - unset($status[$k]); - } - } - - if (!in_array('php-format', $status) && $phpformat) { - $status[] = 'php-format'; - } - - if (!in_array('fuzzy', $status) && $fuzzy) { - $status[] = 'fuzzy'; - } - - $status = array_unique($status); - $po->status[$decstr] = $status; - - $status = ''; - if (preg_match('/(#,.*)$/', $comments, $m)) { - $status = $m[1]; - } - - if (count($po->status[$decstr])) { - $newstatus = "#, " . implode(', ', $po->status[$decstr]); - } else { - $newstatus = ""; - } - - $newcomments = str_replace($status, $newstatus, $comments); - - $po->comments[$decstr] = $newcomments; - $po->strings[$decstr] = Translate_Display::convert_string($msgstr); - $po->save($pofile); -} - -// - -/* Set up the template fields. */ -$template->set('menu', Babel::getMenu()->render()); - -Horde::startBuffer(); -$notification->notify(array('listeners' => 'status')); -$template->set('notify', Horde::endBuffer()); - -/* Create upload form */ -$form = new Horde_Form($vars, _("View Translation"), $show); - -if (!$app) { - $form->setButtons(_("View")); - $form->addVariable(_("Module"), 'module', 'enum', true, false, null, array(Babel::listApps(), true)); - $form->addVariable('', '', 'spacer', true); - - $renderer_params = array(); - $renderer = new Horde_Form_Renderer($renderer_params); - $renderer->setAttrColumnWidth('20%'); - - $form->renderActive($renderer, $vars, Horde::selfURL(), 'post'); -} else { - - if (Babel::hasPermission('view', 'tabs', Horde_Perms::EDIT)) { - $hmenu_desc = _("Edit Header"); - $url = Horde::url('edit.php'); - $url = Horde_Util::addParameter($url, array('module' => $app, - 'url' => 'view')); - - $hmenu = Horde::link($url, $hmenu_desc, 'menuitem', null); - $hmenu .= Horde::img('edit.png', null, $hmenu_desc) . ' ' . $hmenu_desc . ' '; - } else { - $hmenu = ''; - } - - Translate_Display::header(_("Meta Informations"), $hmenu); - echo ''; - $i = 0; - foreach($po->meta as $k => $v) { - echo ''; - } - echo '
'; - echo $k; - echo ''; - echo htmlentities($v); - echo '
'; - Translate_Display::info(); - - Translate_Display::header(_("Statistic")); - - $report = Translate::stats($app, $lang); - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - echo "\n"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\n\t"; - echo "\t"; - - echo '
' . _("Language") . '' . _("Locale") . '' . _("Status") . '' . _("Translated") . '' . _("Fuzzy") . '' . _("Untranslated") . '' . _("Obsolete") . '
" . Horde_Nls::$config['languages'][$lang] . "" . $lang . "" . Translate_Display::create_bargraph(@$report[$lang][2], @$report[$lang][0]) . "" . @$report[$lang][2] . "" . @$report[$lang] [3] . "" . @$report[$lang][4] . "" . @$report[$lang][5] . "
'; - Translate_Display::info(); - - $filter_html = ''; - $filter_html .= '
'; - $filter_html .= ''; - $filter_html .= Horde::img('edit.png') . ' '; - $filter_html .= '' . _("Filter: ") . ''; - $filter_html .= '[ '; - if (!$filter) { - $hmenu_desc = '' . _("All") . ''; - } else { - $hmenu_desc = _("All"); - } - $url = Horde::url('view.php'); - $url = Horde_Util::addParameter($url, array('module' => $app)); - $filter_html .= Horde::link($url, _("Edit Mode"), 'menuitem', null). ' ' . $hmenu_desc . ' '; - $filter_html .= '| '; - - if ($filter == 'translated') { - $hmenu_desc = '' . _("Translated") . ''; - } else { - $hmenu_desc = _("Translated"); - } - $url = Horde::url('view.php'); - $url = Horde_Util::addParameter($url, array('module' => $app, 'filter' => 'translated')); - $filter_html .= Horde::link($url, $hmenu_desc, 'menuitem', null). ' ' . $hmenu_desc . ' '; - $filter_html .= '| '; - - - if ($filter == 'fuzzy') { - $hmenu_desc = '' . _("Fuzzy") . ''; - } else { - $hmenu_desc = _("Fuzzy"); - } - $url = Horde::url('view.php'); - $url = Horde_Util::addParameter($url, array('module' => $app, 'filter' => 'fuzzy')); - $filter_html .= Horde::link($url, $hmenu_desc, 'menuitem', null). ' ' . $hmenu_desc . ' '; - $filter_html .= '| '; - - if ($filter == 'untranslated') { - $hmenu_desc = '' . _("Untranslated") . ''; - } else { - $hmenu_desc = _("Untranslated"); - } - $url = Horde::url('view.php'); - $url = Horde_Util::addParameter($url, array('module' => $app, 'filter' => 'untranslated')); - $filter_html .= Horde::link($url, $hmenu_desc, 'menuitem', null). ' ' . $hmenu_desc . ' '; - $filter_html .= '] '; - - $filter_html .= ''; - $filter_html .= ''; - $filter_html .= ''; - $filter_html .= ''; - $filter_html .= ''; - $filter_html .= ''; - $filter_html .= '
'; - - $perpage = 100; - - foreach($po->strings as $msgid => $msgstr) { - if ($filter && !in_array($filter, $po->status[$msgid])) { - unset($po->strings[$msgid]); - unset($po->status[$msgid]); - unset($po->ref[$msgid]); - } - if ($search && !preg_match(';' . $search . ';i', $msgid)) { - unset($po->strings[$msgid]); - unset($po->status[$msgid]); - unset($po->ref[$msgid]); - } - } - - $numitem = count($po->strings); - // Set list min/max values - $min = $page * $perpage; - while ($min > $numitem) { - $page--; - $min = $page * $perpage; - } - $max = $min + $perpage; - - // Start start/end items (according to current page) - $start = ($page * $perpage) + 1; - $end = min($numitem, $start + $perpage - 1); - - $cntstr = 0; - - $pageinf = ' [' . sprintf(_("%s to %s of %s"), $start, $end, $numitem) . ']'; - Translate_Display::header(_("Translations") . $pageinf, $filter_html); - - foreach($po->strings as $msgid => $msgstr) { - - $cntstr++; - - if ($start && $cntstr < $start) { - continue; - } - - if ($end && $cntstr > $end) { - break; - } - - if ($filter && !in_array($filter, $po->status[$msgid])) { - continue; - } - - $encstr = base64_encode($msgid); - - $bgcolor = '1px #000000'; - if (in_array('fuzzy', $po->status[$msgid])) { - $bgcolor = '3px #FFFF00'; - } - - if (in_array('untranslated', $po->status[$msgid])) { - $bgcolor = '3px #FF0000'; - } - - $locked = false; - if ($curlock = $locks->getLocks(md5($encstr), $lockscope)) { - foreach($curlock as $lid => $linfo) { - if ($linfo['lock_scope'] == md5($encstr)) { - $bgcolor = '3px #FF00FF'; - $locked = $linfo['lock_owner']; - } - } - } - - if ($editmode && $cstring == $encstr) { - - // Lock the current item for 5 minutes - $locks->setLock($GLOBALS['registry']->getAuth(), md5($encstr), $lockscope, 300); - - echo '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - - - ?> - - - - - - - - - - - - - - - -
MSGIDREFERENCESSTATUS
-
  -
- - -ref[$msgid] as $k => $v) { - if (preg_match('/(.*):(.*)/', $v, $m)) { - $sfile = $m[1]; - $sline = $m[2]; - - if (Babel::hasPermission('viewsource', 'tabs', Horde_Perms::EDIT)) { - $surl = Horde::url('viewsource.php'); - $surl = Horde_Util::addParameter($surl, array('module' => $app, - 'file' => $sfile, - 'line' => $sline)); - - $onclick = "viewwindow=window.open('". $surl . "', 'viewsource', 'toolbar=no,location=no,status=yes,scrollbars=yes,resizable=yes,width=650,height=350,left=100,top=100'); if(window.focus) { viewwindow.focus()} ; return false;"; - - $surl = Horde::link('#', $sline, null, null, $onclick); - $surl .= $sline . ''; - $surl = str_replace('&', '&', $surl); - } else { - $surl = $sline; - } - - $ref[$sfile][] = $surl; - } - } - - $i = 0; - foreach($ref as $k => $v) { - echo sprintf("", ($i++ %2), $k, implode(' | ', $v)); - } - ?> -
%s[ %s ]
-
-status[$msgid])) { - echo '' . ' php-format
'; - } else { - echo '' . ' php-format
'; - } - if (in_array('fuzzy', $po->status[$msgid])) { - echo '' . ' fuzzy
'; - } else { - echo '' . ' fuzzy
'; - } - } else { - echo implode('
', $po->status[$msgid]); - } - ?> - -
- - - - - -
MSGSTR - $app, 'cstring' => $encstr, 'editmode' => 1, 'page' => $page, 'filter' => $filter, 'search' => $search)); - $surl .= "#" . md5($encstr); - - echo Horde::link($surl, _("Edit Translation")) . Horde::img('babel.png') . ' ' ._("Edit Translation") . ""; - } elseif ($editmode && $cstring == $encstr) { - echo ''; - echo ' '; - echo ''; - } - } - } -?>
-
-' . Translate_Display::display_string($msgstr) . '
'; - } else { - if (in_array('fuzzy', $po->status[$msgid]) && preg_match('/#-#-#-#-#/', $msgstr)) { - preg_match_all('/(#-#-#-#-#\s+(.*?)\s+#-#-#-#-#(\n)*(.*))+/', Translate_Display::display_string($msgstr), $matches, PREG_SET_ORDER); - foreach($matches as $m) { - echo sprintf("%s - %s
", $m[4], $m[2]); - } - } else { - echo Translate_Display::display_string($msgstr) . "
"; - } - } -?>  -
-

-'; - } - - // print "STAT " . implode(', ', $po->status[$msgid]) . "
"; - } -} - -?> - - $perpage): ?> - -
- $editmode, - 'module' => $app, - 'filter' => $filter, - 'search' => $search)); - $pager = new Horde_Core_Ui_Pager('page', $vars, array('num' => $numitem, 'url' => $viewurl, 'page_count' => 10, 'perpage' => $perpage)); - echo $pager->render($page, $numitem, $viewurl); -?> -
- - -get('templates', 'horde') . '/common-footer.inc'; diff --git a/babel/viewsource.php b/babel/viewsource.php deleted file mode 100644 index 74228d7b5..000000000 --- a/babel/viewsource.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @package Babel - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$app = Horde_Util::getFormData('module'); -$sfile = Horde_Util::getFormData('file'); -$sline = Horde_Util::getFormData('line'); - -if ($app == 'horde') { - $srcfile = realpath(sprintf("%s/%s", HORDE_BASE, $sfile)); -} else { - $srcfile = realpath(sprintf("%s/%s/%s", HORDE_BASE, $app, $sfile)); -} - -if (empty($srcfile)) { - throw new Horde_Exception(_("Missing filename!")); -} - -$rpath = realpath(HORDE_BASE); -if (!preg_match(";$rpath;", $srcfile)) { - throw new Horde_Exception(sprintf(_("Access denied to %s"), $srcfile)); -} - -// Get File content -$src = file_get_contents($srcfile); - -/* Render the page. */ -require BABEL_TEMPLATES . '/common-header.inc'; - -Translate_Display::header(sprintf(_("View source: %s"), str_replace(realpath(HORDE_BASE) . '/', '', $srcfile))); - -printCode($src, $sline, 10); - -require $registry->get('templates', 'horde') . '/common-footer.inc'; - -function printCode($code, $sline = 1, $sdiff = 10) { - if (!is_array($code)) $code = explode("\n", $code); - - $count_lines = count($code); - $r = ''; - - $from = $sline - $sdiff; - $to = $sline + $sdiff; - - foreach ($code as $line => $code_line) { - - if ($from && $line < $from) { - continue; - } - - if ($to && $line > $to) { - break; - } - - $r1 = ($line + 1); - - if (ereg("<\?(php)?[^[:graph:]]", $code_line)) { - $r2 = highlight_string($code_line, 1)."
"; - } else { - $r2 = ereg_replace("(<\?php )+", "", highlight_string(""; - } - - if ($r1 == $sline) { - $r .= sprintf('

%s %s
%s %s
' . $r . '
'; - - echo "
".$r."
"; -} diff --git a/crumb/COPYING b/crumb/COPYING deleted file mode 100644 index a6b67561a..000000000 --- a/crumb/COPYING +++ /dev/null @@ -1,280 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright 1989, 1991 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -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 Program or any portion -of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -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 Program, 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 Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) 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; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, 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 executable. However, as a -special exception, the source code 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. - -If distribution of executable or 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 counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. 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 Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program 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 to -this License. - - 7. 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 Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program 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 Program. - -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. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program 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. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 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 Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, 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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. 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 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. - - END OF TERMS AND CONDITIONS diff --git a/crumb/LICENSE.ASL b/crumb/LICENSE.ASL deleted file mode 100644 index 80a80caeb..000000000 --- a/crumb/LICENSE.ASL +++ /dev/null @@ -1,48 +0,0 @@ -Version 1.0 - -Copyright 2006-2010 The Horde Project. 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 acknowledgment: - - "This product includes software developed by the Horde Project - (http://www.horde.org/)." - -Alternately, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names "Horde", "The Horde Project", and "Skeleton" must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -core@horde.org. - -5. Products derived from this software may not be called "Horde" or -"Skeleton", nor may "Horde" or "Skeleton" appear in their name, without -prior written permission of the Horde Project. - -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 HORDE PROJECT 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 Horde Project. For more information on -the Horde Project, please see . diff --git a/crumb/LICENSE.BSDL b/crumb/LICENSE.BSDL deleted file mode 100644 index ea2f0d10b..000000000 --- a/crumb/LICENSE.BSDL +++ /dev/null @@ -1,24 +0,0 @@ -Copyright 2006-2010 The Horde Project. 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. - -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 HORDE PROJECT -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/crumb/README b/crumb/README deleted file mode 100644 index 6a3190491..000000000 --- a/crumb/README +++ /dev/null @@ -1,86 +0,0 @@ -What is Crumb? -================= - -.. contents:: Contents -.. section-numbering:: - -Crumb is a light-weight CRM application. By creating the concept of a client -within Horde, Crumb allows a single place to manage functionality in -several applications with data related to a client. - -This software is OSI Certified Open Source Software. OSI Certified is a -certification mark of the `Open Source Initiative`_. - -.. _`Open Source Initiative`: http://www.opensource.org/ - - -Obtaining Crumb ------------------- - -Further information on Crumb and the latest version can be obtained at - - http://www.horde.org/crumb/ - - -Documentation -------------- - -The following documentation is available in the Crumb distribution: - -:README_: This file -:COPYING_: Copyright and license information -:LICENSE_: Copyright and license information -:`docs/CHANGES`_: Changes by release -:`docs/CREDITS`_: Project developers -:`docs/INSTALL`_: Installation instructions and notes -:`docs/TODO`_: Development TODO list -:`docs/UPGRADING`_: Pointers on upgrading from previous Crumb versions - - -Installation ------------- - -Instructions for installing Crumb can be found in the file INSTALL_ in the -``docs/`` directory of the Crumb distribution. - - -Assistance ----------- - -If you encounter problems with Crumb, help is available! - -The Horde Frequently Asked Questions List (FAQ), available on the Web at - - http://www.horde.org/faq/ - -The Horde Project runs a number of mailing lists, for individual applications -and for issues relating to the project as a whole. Information, archives, and -subscription information can be found at - - http://www.horde.org/mail/ - -Lastly, Horde developers, contributors and users also make occasional -appearances on IRC, on the channel #horde on the freenode Network -(irc.freenode.net). - - -Licensing ---------- - -For licensing and copyright information, please see the file COPYING_/LICENSE_ -in the Crumb distribution. - -Thanks, - -The Crumb team - - -.. _README: ?f=README.html -.. _COPYING: http://www.horde.org/licenses/gpl.php -.. _LICENSE: http://www.horde.org/licenses/asl.php -.. _docs/CHANGES: ?f=CHANGES.html -.. _docs/CREDITS: ?f=CREDITS.html -.. _INSTALL: -.. _docs/INSTALL: ?f=INSTALL.html -.. _docs/TODO: ?f=TODO.html -.. _docs/UPGRADING: ?f=UPGRADING.html diff --git a/crumb/addclient.php b/crumb/addclient.php deleted file mode 100644 index 9335742ad..000000000 --- a/crumb/addclient.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ - -@define('CRUMB_BASE', dirname(__FILE__)); -require_once CRUMB_BASE . '/lib/base.php'; -require_once 'Horde/Form.php'; -require_once 'Horde/Form/Renderer.php'; -require_once CRUMB_BASE . '/lib/Forms/AddClient.php'; - -$vars = Horde_Variables::getDefaultVariables(); -$formname = $vars->get('formname'); - -$addform = new Horde_Form_AddClient($vars); -if (is_a($addform, 'PEAR_Error')) { - Horde::logMessage($addform, 'ERR'); - $notification->push(_("An internal error has occurred. Details have been logged for the administrator.")); - $addform = null; -} - -if ($addform->validate($vars)) { -print_r($addform->getInfo()); -} - -$url = Horde::url('addclient.php'); -$title = _("Add New Client"); - -require CRUMB_TEMPLATES . '/common-header.inc'; -require CRUMB_TEMPLATES . '/menu.inc'; - -if (!empty($addform)) { - $addform->renderActive(null, null, $url, 'post'); -} - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/crumb/config/conf.bak.php b/crumb/config/conf.bak.php deleted file mode 100644 index e69de29bb..000000000 diff --git a/crumb/config/conf.php b/crumb/config/conf.php deleted file mode 100644 index 55865e188..000000000 --- a/crumb/config/conf.php +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Storage System Settings - sql - - - - crumb_clients - - - - - - - - Menu Settings - - - - - - - diff --git a/crumb/config/prefs.php.dist b/crumb/config/prefs.php.dist deleted file mode 100644 index 391652271..000000000 --- a/crumb/config/prefs.php.dist +++ /dev/null @@ -1,21 +0,0 @@ - _("Sample Prefs"), - 'label' => _("Sample Pref"), - 'desc' => _("Set your sample preference."), - 'members' => array('sample') -); - -$_prefs['sample'] = array( - 'value' => '', - 'locked' => false, - 'shared' => false, - 'type' => 'text', - 'desc' => _("This is your sample preference.") -); diff --git a/crumb/contactsearch.php b/crumb/contactsearch.php deleted file mode 100644 index 4d8518490..000000000 --- a/crumb/contactsearch.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ - -@define('CRUMB_BASE', dirname(__FILE__)); -require_once CRUMB_BASE . '/lib/base.php'; -require_once 'Horde/Form.php'; -require_once 'Horde/Form/Renderer.php'; -require_once CRUMB_BASE . '/lib/Forms/ContactSearch.php'; - -$vars = Horde_Variables::getDefaultVariables(); - -$searchform = new Horde_Form_ContactSearch($vars); - -$info = array(); -if ($searchform->validate($vars)) { -echo "Success!"; -} - -$url = Horde::url(basename(__FILE__)); -$title = $searchform->getTitle(); - -require CRUMB_TEMPLATES . '/common-header.inc'; -require CRUMB_TEMPLATES . '/menu.inc'; - -$searchform->renderActive(null, null, $url, 'post'); - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/crumb/docs/CHANGES b/crumb/docs/CHANGES deleted file mode 100644 index 141c0cc98..000000000 --- a/crumb/docs/CHANGES +++ /dev/null @@ -1,5 +0,0 @@ ---- -0.1 ---- - -[xyz] Initial Release diff --git a/crumb/docs/CREDITS b/crumb/docs/CREDITS deleted file mode 100644 index 62c26b77a..000000000 --- a/crumb/docs/CREDITS +++ /dev/null @@ -1,24 +0,0 @@ -=========================== - Crumb Development Team -=========================== - - -Core Developers -=============== -Ben Klang - - -Drivers -======= - - - -Localization -============ - -===================== ====================================================== -===================== ====================================================== - - -Contributions -============= diff --git a/crumb/docs/INSTALL b/crumb/docs/INSTALL deleted file mode 100644 index 4d0db66d4..000000000 --- a/crumb/docs/INSTALL +++ /dev/null @@ -1,237 +0,0 @@ -========================= - Installing Crumb 1.0 -========================= - -.. contents:: Contents -.. section-numbering:: - -This document contains instructions for installing the Crumb ... - -For information on the capabilities and features of Crumb, see the file -README_ in the top-level directory of the Crumb distribution. - - -Obtaining Crumb -================== - -Crumb can be obtained from the Horde website and FTP server, at - - http://www.horde.org/crumb/ - - ftp://ftp.horde.org/pub/crumb/ - -Or use the mirror closest to you: - - http://www.horde.org/mirrors.php - -Bleeding-edge development versions of Crumb are available via CVS; see the -file `horde/docs/HACKING`_ in the Horde distribution, or the website -http://www.horde.org/source/, for information on accessing the Horde CVS -repository. - - -Prerequisites -============= - -To function properly, Crumb **requires** the following: - -1. A working Horde installation. - - Crumb runs within the `Horde Application Framework`_, a set of common - tools for Web applications written in PHP. You must install Horde before - installing Crumb. - - .. Important:: Crumb 1.0 requires version 3.0+ of the Horde Framework - - earlier versions of Horde will **not** work. - - .. _`Horde Application Framework`: http://www.horde.org/horde/ - - The Horde Framework can be obtained from the Horde website and FTP server, - at - - http://www.horde.org/horde/ - - ftp://ftp.horde.org/pub/horde/ - - Many of Crumb's prerequisites are also Horde prerequisites. - - .. Important:: Be sure to have completed all of the steps in the - `horde/docs/INSTALL`_ file for the Horde Framework before - installing Crumb. - -2. The following PHP capabilities: - - a. FOO support ``--with-foo`` [OPTIONAL] - - Description of Foo and what it is used for. - -3. The following PEAR packages: - (See `horde/docs/INSTALL`_ for instructions on installing PEAR packages) - - a. PEAR_Package x.x.x [OPTIONAL] - - Crumb uses the Foo_Bar class for... - -4. The following PECL modules: - (See `horde/docs/INSTALL`_ for instructions on installing PECL modules) - - a. pecl_package x.x.x [OPTIONAL] - - pecl_package is required to... - -5. Something else. - -The following items are not required, but are strongly **recommended**: - -1. Yet something else. - - -Installing Crumb -=================== - -Crumb is written in PHP, and must be installed in a web-accessible -directory. The precise location of this directory will differ from system to -system. Conventionally, Crumb is installed directly underneath Horde in the -web server's document tree. - -Since Crumb is written in PHP, there is no compilation necessary; simply -expand the distribution where you want it to reside and rename the root -directory of the distribution to whatever you wish to appear in the URL. For -example, with the Apache web server's default document root of -``/usr/local/apache/htdocs``, you would type:: - - cd /usr/local/apache/htdocs/horde - tar zxvf /path/to/crumb-h3-x.y.z.tar.gz - mv crumb-h3-x.y.z crumb - -and would then find Crumb at the URL:: - - http://your-server/horde/crumb/ - - -Configuring Crumb -==================== - -1. Configuring Horde for Crumb - - a. Register the application - - In ``horde/config/registry.php``, find the ``applications['crumb']`` - stanza. The default settings here should be okay, but you can change - them if desired. If you have changed the location of Crumb relative - to Horde, either in the URL, in the filesystem or both, you must update - the ``fileroot`` and ``webroot`` settings to their correct values. - -2. Creating the database tables - - The specific steps to create Crumb's database tables depend on which - database you've chosen to use. - - First, look in ``scripts/sql/`` to see if a script already exists for your - database type. If so, you should be able to simply execute that script as - superuser in your database. (Note that executing the script as the "horde" - user will probably fail when granting privileges.) - - If such a script does not exist, you'll need to build your own, using the - file ``crumb.sql`` as a starting point. If you need assistance in - creating database tables, you may wish to let us know on the Crumb - mailing list. - - You will also need to make sure that the "horde" user in your database has - table-creation privileges, so that the tables that `PEAR DB`_ uses to - provide portable sequences can be created. - - .. _`PEAR DB`: http://pear.php.net/DB - -3. Configuring Crumb - - To configure Crumb, change to the ``config/`` directory of the installed - distribution, and make copies of all of the configuration ``dist`` files - without the ``dist`` suffix:: - - cd config/ - for foo in *.dist; do cp $foo `basename $foo .dist`; done - - Or on Windows:: - - copy *.dist *. - - Documentation on the format and purpose of those files can be found in each - file. You may edit these files if you wish to customize Crumb's - appearance and behavior. With one exception (``foo.php``) the defaults will - be correct for most sites. - - You must login to Horde as a Horde Administrator to finish the - configuration of Crumb. Use the Horde ``Administration`` menu item to - get to the administration page, and then click on the ``Configuration`` - icon to get the configuration page. Select ``Crumb Name`` from the - selection list of applications. Fill in or change any configuration values - as needed. When done click on ``Generate Crumb Name Configuration`` to - generate the ``conf.php`` file. If your web server doesn't have write - permissions to the Crumb configuration directory or file, it will not be - able to write the file. In this case, go back to ``Configuration`` and - choose one of the other methods to create the configuration file - ``crumb/config/conf.php``. - - Note for international users: Crumb uses GNU gettext to provide local - translations of text displayed by applications; the translations are found - in the ``po/`` directory. If a translation is not yet available for your - locale (and you wish to create one), see the ``horde/po/README`` file, or - if you're having trouble using a provided translation, please see the - `horde/docs/TRANSLATIONS`_ file for instructions. - -4. More instructions, upgrading, securing, etc. - -5. Testing Crumb - - Once you have configured Crumb, bring up the included test page in your - Web browser to ensure that all necessary prerequisites have been met. See - the `horde/docs/INSTALL`_ document for further details on the Horde test - script. - - The test script will also allow you to test... - - Next, use Crumb to.... Test at least the following: - - - Foo - - Bar - - -Known Problems -============== - -... - - -Obtaining Support -================= - -If you encounter problems with Crumb, help is available! - -The Horde Frequently Asked Questions List (FAQ), available on the Web at - - http://www.horde.org/faq/ - -The Horde Project runs a number of mailing lists, for individual applications -and for issues relating to the project as a whole. Information, archives, and -subscription information can be found at - - http://www.horde.org/mail/ - -Lastly, Horde developers, contributors and users may also be found on IRC, -on the channel #horde on the Freenode Network (irc.freenode.net). - -Please keep in mind that Crumb is free software written by volunteers. -For information on reasonable support expectations, please read - - http://www.horde.org/support.php - -Thanks for using Crumb! - -The Crumb team - - -.. _README: ?f=README.html -.. _`horde/docs/HACKING`: ../../horde/docs/?f=HACKING.html -.. _`horde/docs/INSTALL`: ../../horde/docs/?f=INSTALL.html -.. _`horde/docs/TRANSLATIONS`: ../../horde/docs/?f=TRANSLATIONS.html diff --git a/crumb/docs/RELEASE_NOTES b/crumb/docs/RELEASE_NOTES deleted file mode 100644 index ef85ebaff..000000000 --- a/crumb/docs/RELEASE_NOTES +++ /dev/null @@ -1,49 +0,0 @@ -notes['fm']['focus'] = 4; - -/* Mailing list release notes. */ -$this->notes['ml']['changes'] = <<notes['fm']['changes'] = <<notes['name'] = 'Crumb'; -$this->notes['fm']['project'] = 'crumb'; -$this->notes['fm']['branch'] = 'Default'; diff --git a/crumb/docs/TODO b/crumb/docs/TODO deleted file mode 100644 index bce715fbf..000000000 --- a/crumb/docs/TODO +++ /dev/null @@ -1,5 +0,0 @@ -================================ - Crumb Development TODO List -================================ - -- Example todo diff --git a/crumb/index.php b/crumb/index.php deleted file mode 100644 index 1cbd4a60b..000000000 --- a/crumb/index.php +++ /dev/null @@ -1,11 +0,0 @@ - - */ - -require dirname(__FILE__) . '/listclients.php'; diff --git a/crumb/lib/Application.php b/crumb/lib/Application.php deleted file mode 100644 index d9510ec54..000000000 --- a/crumb/lib/Application.php +++ /dev/null @@ -1,16 +0,0 @@ - array('type' => 'text', - 'name' => _("Color"), - 'default' => '#ff0000')); - } - - /** - * The title to go in this block. - * - * @return string The title text. - */ - function _title() - { - return _("Color"); - } - - /** - * The content to go in this block. - * - * @return string The content - */ - function _content() - { - $html = ''; - $html .= ''; - $html .= '
 
'; - - return sprintf($html, $this->_params['color']); - } - -} diff --git a/crumb/lib/Crumb.php b/crumb/lib/Crumb.php deleted file mode 100644 index d7ab8fe70..000000000 --- a/crumb/lib/Crumb.php +++ /dev/null @@ -1,29 +0,0 @@ - - * @package Crumb - */ -class Crumb { - - /** - * Build Crumb's list of menu items. - */ - function getMenu() - { - global $conf, $registry, $browser, $print_link; - - $menu = new Horde_Menu(Horde_Menu::MASK_ALL); - $menu->add(Horde::url('listclients.php'), _("List Clients"), 'user.png', Horde_Themes::img(null, 'horde')); - $menu->add(Horde::url('addclient.php'), _("Add Client"), 'user.png', Horde_Themes::img(null, 'horde')); - - return $menu; - } - -} diff --git a/crumb/lib/Driver.php b/crumb/lib/Driver.php deleted file mode 100644 index 7fcbfa3dc..000000000 --- a/crumb/lib/Driver.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package Crumb - */ -class Crumb_Driver { - - - /** - * Lists all clients. - * - * @return array Returns a list of all foos. - */ - function listClients() - { - return $this->_listClients(); - } - - /** - * Attempts to return a concrete Crumb_Driver instance based on $driver. - * - * @param string $driver The type of the concrete Crumb_Driver subclass - * to return. The class name is based on the - * storage driver ($driver). The code is - * dynamically included. - * - * @param array $params A hash containing any additional configuration - * or connection parameters a subclass might need. - * - * @return Crumb_Driver The newly created concrete Crumb_Driver - * instance, or false on an error. - */ - function factory($driver = null, $params = null) - { - if ($driver === null) { - $driver = $GLOBALS['conf']['storage']['driver']; - } - $driver = basename($driver); - - if ($params === null) { - $params = Horde::getDriverConfig('storage', $driver); - } - - $class = 'Crumb_Driver_' . $driver; - if (!class_exists($class)) { - include dirname(__FILE__) . '/Driver/' . $driver . '.php'; - } - if (class_exists($class)) { - return new $class($params); - } else { - return false; - } - } - -} diff --git a/crumb/lib/Driver/sql.php b/crumb/lib/Driver/sql.php deleted file mode 100644 index d12dbd156..000000000 --- a/crumb/lib/Driver/sql.php +++ /dev/null @@ -1,127 +0,0 @@ - - * 'phptype' The database type (e.g. 'pgsql', 'mysql', etc.). - * 'table' The name of the foo table in 'database'. - * 'charset' The database's internal charset. - * - * Required by some database implementations:
- *      'database'      The name of the database.
- *      'hostspec'      The hostname of the database server.
- *      'protocol'      The communication protocol ('tcp', 'unix', etc.).
- *      'username'      The username with which to connect to the database.
- *      'password'      The password associated with 'username'.
- *      'options'       Additional options to pass to the database.
- *      'tty'           The TTY on which to connect to the database.
- *      'port'          The port on which to connect to the database.
- * - * The table structure can be created by the scripts/sql/crumb_foo.sql - * script. - * - * Copyright 2007-2010 The Horde Project (http://www.horde.org/) - * - * See the enclosed file COPYING for license information (GPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. - * - * @author Ben Klang - * @package Crumb - */ -class Crumb_Driver_sql extends Crumb_Driver { - - /** - * Hash containing connection parameters. - * - * @var array - */ - var $_params = array(); - - /** - * Handle for the current database connection. - * - * @var DB - */ - var $_db; - - /** - * Handle for the current database connection, used for writing. Defaults - * to the same handle as $_db if a separate write database is not required. - * - * @var DB - */ - var $_write_db; - - /** - * Boolean indicating whether or not we're connected to the SQL server. - * - * @var boolean - */ - var $_connected = false; - - /** - * Constructs a new SQL storage object. - * - * @param array $params A hash containing connection parameters. - */ - function Crumb_Driver_sql($params = array()) - { - $this->_params = $params; - } - - /** - * Retrieves the list of clients from the database. - * - * @return boolean|PEAR_Error True on success, PEAR_Error on failure. - */ - function _listClients() - { - /* Make sure we have a valid database connection. */ - $this->_connect(); - - /* Build the SQL query. */ - $query = 'SELECT * FROM ' . $this->_params['table']; - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Crumb_Driver_sql::_listClients(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $result = $this->_db->getAll($query, array(), DB_FETCHMODE_ASSOC); - - return $result; - } - - /** - * Attempts to open a persistent connection to the SQL server. - * - * @return boolean True on success. - */ - function _connect() - { - if ($this->_connected) { - return true; - } - - $this->_db = $GLOBALS['injector']->getInstance('Horde_Db_Pear')->getDb('read', 'crumb', 'storage'); - $this->_write_db = $GLOBALS['injector']->getInstance('Horde_Db_Pear')->getDb('rw', 'crumb', 'storage'); - - return true; - } - - /** - * Disconnects from the SQL server and cleans up the connection. - * - * @return boolean True on success, false on failure. - */ - function _disconnect() - { - if ($this->_connected) { - $this->_connected = false; - $this->_db->disconnect(); - $this->_write_db->disconnect(); - } - - return true; - } - -} diff --git a/crumb/lib/Forms/AddClient.php b/crumb/lib/Forms/AddClient.php deleted file mode 100644 index 9062f0965..000000000 --- a/crumb/lib/Forms/AddClient.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (GPL). If you - * did not receive this file, see http://www.horde.org/licenses/gpl.php. - * - * @author Ben Klang - * @package Crumb - */ -require_once 'Horde/Form/Action.php'; - -class Horde_Form_AddClient extends Horde_Form -{ - function Horde_Form_AddClient(&$vars) - { - parent::Horde_Form($vars, _("Add New Client")); - - $addOrPick = array('create' => _("Create New"), - 'assign' => _("Assign Existing")); - - $action = &Horde_Form_Action::factory('reload'); - - $select = &$this->addVariable(_("Contact Information"), 'chooseContact', 'enum', true, false, null, array($addOrPick, true)); - $select->setAction($action); - $select->setOption('trackchange', true); - - if ($vars->get('chooseContact') == 'create') { - try { - $turbaform = $GLOBALS['registry']->call('contacts/getAddClientForm', array(&$vars)); - } catch (Horde_Exception $e) { - Horde::logMessage($e, 'ERR'); - $notification->push(_("An internal error has occurred. Details have beenlogged for the administrator.")); - $addform = null; - } - $elements = $turbaform->getVariables(); - foreach ($elements as $element) { - $this->importVariable($element); - } - } elseif ($vars->get('chooseContact') == 'assign') { - require_once CRUMB_BASE . '/lib/Forms/ContactSearch.php'; - $searchform = new Horde_Form_ContactSearch($vars); - $elements = $searchform->getVariables(); - foreach ($elements as $element) { - $this->importVariable($element); - } - } - - $action = &Horde_Form_Action::factory('reload'); - $select = &$this->addVariable(_("Ticket Queue"), 'chooseQueue', 'enum', true, false, null, array($addOrPick, true)); - $select->setAction($action); - $select->setOption('trackchange', true); - - if ($vars->get('chooseQueue') == 'create') { - try { - $whupsform = $GLOBALS['registry']->call('tickets/getAddQueueForm', array(&$vars)); - } catch (Horde_Exception $e) { - Horde::logMessage($e, 'ERR'); - $notification->push(_("An internal error has occurred. Details have been logged for the administrator.")); - $addform = null; - } - $elements = $whupsform->getVariables(); - foreach ($elements as $element) { - $this->importVariable($element); - } - } elseif ($vars->get('chooseQueue') == 'assign') { - $queues = $GLOBALS['registry']->listQueues(); - } - - $action = &Horde_Form_Action::factory('reload'); - $select = &$this->addVariable(_("Group"), 'rectype', 'enum', true, false, null, array($addOrPick, true)); - $select->setAction($action); - $select->setOption('trackchange', true); - - return true; - } -} diff --git a/crumb/lib/Forms/ContactSearch.php b/crumb/lib/Forms/ContactSearch.php deleted file mode 100644 index e6f06d408..000000000 --- a/crumb/lib/Forms/ContactSearch.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (GPL). If you - * did not receive this file, see http://www.horde.org/licenses/gpl.php. - * - * @author Ben Klang - * @package Beatnik - */ -class Horde_Form_ContactSearch extends Horde_Form -{ - function Horde_Form_ContactSearch(&$vars) - { - parent::Horde_Form($vars, _("Search for Client Contact Record")); - - $this->addVariable(_("Name"), 'name', 'text', true, false, _("Enter a few characters to search for all clients whose names contain the search text")); - - $name = $vars->get('name'); - if (!empty($name)) { - $results = $GLOBALS['registry']->call('contacts/searchClients', array($name)); - // We only pass one search string so there is only one element at - // the top level of the results array. - $results = array_pop($results); - $contacts = array(); - foreach ($results as $contact) { - $contacts[$contact['__uid']] = $contact['name']; - } - asort($contacts); - $this->addVariable(_("Contact"), 'uid', 'radio', true, false, _("Select the matching contact record or begin a new search above"), array($contacts)); - return true; - } - } -} diff --git a/crumb/lib/base.php b/crumb/lib/base.php deleted file mode 100644 index 56437d84e..000000000 --- a/crumb/lib/base.php +++ /dev/null @@ -1,39 +0,0 @@ - - * - * This file brings in all of the dependencies that every Crumb script will - * need, and sets up objects that all scripts use. - * - * @author Ben Klang - */ - -// Check for a prior definition of HORDE_BASE (perhaps by an auto_prepend_file -// definition for site customization). -if (!defined('HORDE_BASE')) { - @define('HORDE_BASE', dirname(__FILE__) . '/../..'); -} - -// Load the Horde Framework core, and set up inclusion paths. -require_once HORDE_BASE . '/lib/core.php'; - -// Registry. -$registry = new Horde_Registry(); -try { - $registry->pushApp('crumb', array('logintasks' => true)); -} catch (Horde_Exception $e) { - $registry->authenticateFailure('crumb', $e); -} -$conf = &$GLOBALS['conf']; -@define('CRUMB_TEMPLATES', $registry->get('templates')); - -// Define the base file path of Crumb. -@define('CRUMB_BASE', dirname(__FILE__) . '/..'); - -// Crumb driver -$crumb_driver = Crumb_Driver::factory(); - -// Start output compression. -Horde::compressOutput(); diff --git a/crumb/listclients.php b/crumb/listclients.php deleted file mode 100644 index 09af20def..000000000 --- a/crumb/listclients.php +++ /dev/null @@ -1,21 +0,0 @@ - - */ - -@define('CRUMB_BASE', dirname(__FILE__)); -require_once CRUMB_BASE . '/lib/base.php'; - -$clients = $crumb_driver->listClients(); - -$title = _("List"); - -require CRUMB_TEMPLATES . '/common-header.inc'; -require CRUMB_TEMPLATES . '/menu.inc'; -print_r($clients); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/crumb/locale b/crumb/locale deleted file mode 100644 index 26d8318d8..000000000 --- a/crumb/locale +++ /dev/null @@ -1,111 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Horde Project -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: dev@lists.horde.org\n" -"POT-Creation-Date: 2010-08-17 17:46+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: lib/Crumb.php:24 -msgid "Add Client" -msgstr "" - -#: addclient.php:32 lib/Forms/AddClient.php:17 -msgid "Add New Client" -msgstr "" - -#: addclient.php:23 lib/Forms/AddClient.php:59 -msgid "" -"An internal error has occurred. Details have been logged for the " -"administrator." -msgstr "" - -#: lib/Forms/AddClient.php:33 -msgid "" -"An internal error has occurred. Details have beenlogged for the " -"administrator." -msgstr "" - -#: lib/Forms/AddClient.php:20 -msgid "Assign Existing" -msgstr "" - -#: lib/Block/example.php:15 lib/Block/example.php:26 -msgid "Color" -msgstr "" - -#: lib/Forms/ContactSearch.php:30 -msgid "Contact" -msgstr "" - -#: lib/Forms/AddClient.php:24 -msgid "Contact Information" -msgstr "" - -#: lib/Forms/AddClient.php:19 -msgid "Create New" -msgstr "" - -#: lib/Forms/ContactSearch.php:17 -msgid "" -"Enter a few characters to search for all clients whose names contain the " -"search text" -msgstr "" - -#: lib/Block/example.php:3 -msgid "Example Block" -msgstr "" - -#: lib/Forms/AddClient.php:71 -msgid "Group" -msgstr "" - -#: listclients.php:16 -msgid "List" -msgstr "" - -#: lib/Crumb.php:23 -msgid "List Clients" -msgstr "" - -#: lib/Forms/ContactSearch.php:17 -msgid "Name" -msgstr "" - -#: config/prefs.php.dist:10 -msgid "Sample Pref" -msgstr "" - -#: config/prefs.php.dist:9 -msgid "Sample Prefs" -msgstr "" - -#: lib/Forms/ContactSearch.php:15 -msgid "Search for Client Contact Record" -msgstr "" - -#: lib/Forms/ContactSearch.php:30 -msgid "Select the matching contact record or begin a new search above" -msgstr "" - -#: config/prefs.php.dist:11 -msgid "Set your sample preference." -msgstr "" - -#: config/prefs.php.dist:20 -msgid "This is your sample preference." -msgstr "" - -#: lib/Forms/AddClient.php:50 -msgid "Ticket Queue" -msgstr "" diff --git a/crumb/scripts/sql/crumb.sql b/crumb/scripts/sql/crumb.sql deleted file mode 100644 index 355588bef..000000000 --- a/crumb/scripts/sql/crumb.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE crumb_clients ( - client_id INT NOT NULL, - turba_uid VARCHAR(255), - whups_queue INT, - group_id VARCHAR(255), - - PRIMARY KEY (client_id) -); - diff --git a/crumb/templates/common-header.inc b/crumb/templates/common-header.inc deleted file mode 100644 index 1385eaffd..000000000 --- a/crumb/templates/common-header.inc +++ /dev/null @@ -1,29 +0,0 @@ -getCharset()); - header('Vary: Accept-Language'); -} -?> - - - - -' : '' ?> - -get('name'); -if (!empty($title)) { - $page_title .= ' :: ' . $title; -} - -Horde::outputMetaTags(); -Horde::includeScriptFiles(); - -?> -<?php echo htmlspecialchars($page_title) ?> - - - - - diff --git a/crumb/templates/menu.inc b/crumb/templates/menu.inc deleted file mode 100644 index e996c4a13..000000000 --- a/crumb/templates/menu.inc +++ /dev/null @@ -1,5 +0,0 @@ - - -notify(array('listeners' => 'status')) ?> diff --git a/crumb/themes/screen.css b/crumb/themes/screen.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/drag_n_drop_portal/block.php b/drag_n_drop_portal/block.php deleted file mode 100644 index eb3e4886e..000000000 --- a/drag_n_drop_portal/block.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package Folks - */ -define('HORDE_BASE', dirname(__FILE__) . '/..'); -require_once HORDE_BASE . '/lib/base.php'; -require_once 'Horde/Loader.php'; - -// Block to load -$block_id = Horde_Util::getFormData('block'); -list($app, $name) = explode(':', $block_id); - -$block_data = array(); -$block = Horde_Block_Collection::getBlock($app, $name, Horde_Util::getFormData('defaults')); -if ($block instanceof PEAR_Error) { - $block_data['title'] = $block->getMessage(); - $block_data['content'] = $block->getDebugInfo(); -} else { - $block_data['title'] = @$block->getTitle(); - if ($block_data['title'] instanceof PEAR_Error) { - $block_data['title'] = $block_data['title']->getMessage(); - } - $block_data['content'] = @$block->getContent(); - if ($block_data['content'] instanceof PEAR_Error) { - $block_data['content'] = $block_data['content']->getDebugInfo(); - } -} - -echo Horde_Serialize::serialize($block_data, Horde_Serialize::JSON, $GLOBALS['registry']->getCharset()); diff --git a/drag_n_drop_portal/index.php b/drag_n_drop_portal/index.php deleted file mode 100644 index d515a1739..000000000 --- a/drag_n_drop_portal/index.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package Folks - */ -require_once dirname(__FILE__) . '/../lib/base.php'; -require_once 'Horde/Loader.php'; -require_once './lib/Block/Layout/View/js.php'; - -// Load layout from preferences. -$layout_pref = unserialize($prefs->getValue('portal_layout')); -if (!is_array($layout_pref)) { - $layout_pref = array(); -} -if (!count($layout_pref)) { - $layout_pref = Horde_Block_Collection::getFixedBlocks(); -} - -// Render layout. -$view = new Horde_Block_Layout_View_Js($layout_pref); -$layout_html = $view->toHtml(); - -$title = _("Edit yout profile page"); - -Horde::addScriptFile('effects.js', 'horde'); -Horde::addScriptFile('redbox.js', 'horde'); -require HORDE_TEMPLATES . '/common-header.inc'; -require HORDE_TEMPLATES . '/menu/menu.inc'; -?> - - - - - - - - - - -
- - -get('templates', 'horde') . '/common-footer.inc'; diff --git a/drag_n_drop_portal/js/portal.js b/drag_n_drop_portal/js/portal.js deleted file mode 100644 index 60541be0b..000000000 --- a/drag_n_drop_portal/js/portal.js +++ /dev/null @@ -1,366 +0,0 @@ -// Copyright 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// VERSION 1.1-trunk - -if(typeof Draggable == 'undefined') - throw("widget.js requires including script.aculo.us' dragdrop.js library"); - -if(typeof Builder == 'undefined') - throw("widget.js requires including script.aculo.us' builder.js library"); - -// Xilinus namespace -if(typeof Xilinus == 'undefined') - Xilinus = {} - -Builder.dump(); - - -Xilinus.Widget = Class.create(); -Xilinus.Widget.lastId = 0; -Xilinus.Widget.remove = function(element, options) { - if (options && options.afterFinish) - options.afterFinish.call(); -} - -Object.extend(Xilinus.Widget.prototype, { - initialize: function(className, id) { - className = className || "widget"; - this._id = id || ("widget_" + Xilinus.Widget.lastId++); - - this._titleDiv = DIV({className: 'header', id: this._getId("header")}, ""); - this._contentDiv = DIV({className: 'headerbox', id: this._getId("content")}, ""); - this._footerDiv = DIV({className: className + '_statusbar', id: this._getId("footer")}, ""); - - var divHeader = DIV({className: 'header' }, this._titleDiv); - var divContent = DIV({className: 'headerbox' }, this._contentDiv); - var divFooter = DIV({className: className + '_sw' }, this._footerDiv); - - this._div = DIV({className: className + (className != "widget" ? " widget" : ""), id: this._getId()}, [divHeader, divContent, divFooter]); - this._div.widget = this; - - return this; - }, - - destroy: function() { - this._div.remove(); - }, - - getElement: function() { - return $(this._getId()) || $(this._div); - }, - - setTitle: function(title) { - $(this._titleDiv).update(title); - return this; - }, - - getTitle: function(title) { - return $(this._titleDiv) - }, - - setFooter: function(title) { - $(this._footerDiv).update(title); - return this; - }, - - getFooter: function(title) { - return $(this._footerDiv) - }, - - setContent: function(title) { - $(this._contentDiv).update(title); - return this; - }, - - getContent: function(title) { - return $(this._contentDiv) - }, - - updateHeight: function() { - $(this._contentDiv).setStyle({height: null}) - - var h = $(this._contentDiv).getHeight(); - $(this._contentDiv).setStyle({height: h + "px"}) - }, - - // PRIVATE FUNCTIONS - _getId: function(prefix) { - return (prefix ? prefix + "_" : "") + this._id; - } -}); - - -Xilinus.Portal = Class.create() -Object.extend(Xilinus.Portal.prototype, { - lastEvent: null, - widgets: null, - columns: null, - - initialize: function(columns, options) { - this.options = Object.extend({ - url: null, // Url called by Ajax.Request after a drop - onOverWidget: null, // Called when the mouse goes over a widget - onOutWidget: null, // Called when the mouse goes out of a widget - onChange: null, // Called a widget has been move during drag and drop - onUpdate: null, // Called a widget has been move after drag and drop - removeEffect: Xilinus.Widget.remove // Remove effect (by default no effect), you can set it to Effect.SwitchOff for example - }, options) - this._columns = (typeof columns == "string") ? $$(columns) : columns; - this._widgets = new Array(); - this._columns.each(function(element) {Droppables.add(element, {onHover: this.onHover.bind(this), - overlap: "vertical", - accept: this.options.accept})}.bind(this)); - this._outTimer = null; - - // Draggable calls makePositioned for IE fix (??), I had to remove it for all browsers fix :) to handle properly zIndex - this._columns.invoke("undoPositioned"); - - this._currentOverWidget = null; - this._widgetMouseOver = this.widgetMouseOver.bindAsEventListener(this); - this._widgetMouseOut = this.widgetMouseOut.bindAsEventListener(this); - - Draggables.addObserver({ onEnd: this.endDrag.bind(this), onStart: this.startDrag.bind(this) }); - }, - - add: function(widget, columnIndex, draggable) { - draggable = typeof draggable == "undefined" ? true : draggable - // Add to widgets list - this._widgets.push(widget); - if (this.options.accept) - widget.getElement().addClassName(this.options.accept) - // Add element to column - this._columns[columnIndex].appendChild(widget.getElement()); - widget.updateHeight(); - - // Make header draggable - if (draggable) { - widget.draggable = new Draggable(widget.getElement(),{ handle: widget._titleDiv, revert: false}); - widget.getTitle().addClassName("widget_draggable"); - } - - // Update columns heights - this._updateColumnsHeight(); - - // Add mouse observers - if (this.options.onOverWidget) - widget.getElement().immediateDescendants().invoke("observe", "mouseover", this._widgetMouseOver); - if (this.options.onOutWidget) - widget.getElement().immediateDescendants().invoke("observe", "mouseout", this._widgetMouseOut); - }, - - remove: function(widget) { - // Remove from the list - this._widgets.reject(function(w) { return w == widget}); - - // Remove observers - if (this.options.onOverWidget) - widget.getElement().immediateDescendants().invoke("stopObserving", "mouseover", this._widgetMouseOver); - if (this.options.onOutWidget) - widget.getElement().immediateDescendants().invoke("stopObserving", "mouseout", this._widgetMouseOut); - - // Remove draggable - if (widget.draggable) - widget.draggable.destroy(); - - // Remove from the dom - this.options.removeEffect(widget.getElement(), {afterFinish: function() {widget.destroy();}}); - - // Update columns heights - this._updateColumnsHeight(); - }, - - serialize: function() { - parameters = "" - this._columns.each(function(column) { - var p = column.immediateDescendants().collect(function(element) { - return column.id + "[]=" + element.id - }).join("&") - parameters += p + "&" - }); - - return parameters; - }, - - addWidgetControls: function(element) { - $(element).observe("mouseover", this._widgetMouseOver); - $(element).observe("mouseout", this._widgetMouseOut); - }, - - // EVENTS CALLBACKS - widgetMouseOver: function(event) { - this._clearTimer(); - - var element = Event.element(event).up(".widget"); - if (this._currentOverWidget == null || this._currentOverWidget != element) { - if (this._currentOverWidget && this._currentOverWidget != element) - this.options.onOutWidget(this, this._currentOverWidget.widget) - - this._currentOverWidget = element; - this.options.onOverWidget(this, element.widget) - } - }, - - widgetMouseOut: function(event) { - this._clearTimer(); - var element = Event.element(event).up(".widget"); - this._outTimer = setTimeout(this._doWidgetMouseOut.bind(this, element), 100); - }, - - _doWidgetMouseOut: function(element) { - this._currentOverWidget = null; - this.options.onOutWidget(this, element.widget) - }, - - // DRAGGABLE OBSERVER CALLBACKS - startDrag: function(eventName, draggable) { - var widget = draggable.element; - - if (!this._widgets.find(function(w) {return w == widget.widget})) - return; - - var column = widget.parentNode; - - // Create and insert ghost widget - var ghost = DIV({className: 'widget_ghost'}, ""); - $(ghost).setStyle({height: widget.getHeight() + 'px'}) - - column.insertBefore(ghost, widget); - - // IE Does not absolutize properly the widget, needs to set width before - widget.setStyle({width: widget.getWidth() + "px"}); - - // Absolutize and move widget on body - Position.absolutize(widget); - document.body.appendChild(widget); - - // Store ghost to drag widget for later use - draggable.element.ghost = ghost; - - // Store current position - this._savePosition = this.serialize(); - }, - - endDrag: function(eventName, draggable) { - var widget = draggable.element; - if (!this._widgets.find(function(w) {return w == widget.widget})) - return; - - var column = widget.ghost.parentNode; - - column.insertBefore(draggable.element, widget.ghost); - widget.ghost.remove(); - - if (Prototype.Browser.Opera) - widget.setStyle({top: 0, left: 0, width: "100%", height: widget._originalHeight, zIndex: null, opacity: null, position: "relative"}) - else - widget.setStyle({top: null, left: null, width: null, height: widget._originalHeight, zIndex: null, opacity: null, position: "relative"}) - - widget.ghost = null; - widget.widget.updateHeight(); - this._updateColumnsHeight(); - - // Fire events if changed - if (this._savePosition != this.serialize()) { - if (this.options.url) - new Ajax.Request(this.options.url, {parameters: this.serialize()}); - - if (this.options.onUpdate) - this.options.onUpdate(this); - } - }, - - onHover: function(dragWidget, dropon, overlap) { - var offset = Position.cumulativeOffset(dropon); - var x = offset[0] + 10; - var y = offset[1] + (1 - overlap) * dropon.getHeight(); - - // Check over ghost widget - if (Position.within(dragWidget.ghost, x, y)) - return; - - // Find if it's overlapping a widget - var found = false; - var moved = false; - for (var index = 0, len = this._widgets.length; index < len; ++index) { - var w = this._widgets[index].getElement(); - if (w == dragWidget || w.parentNode != dropon) - continue; - - if (Position.within(w, x, y)) { - var overlap = Position.overlap( 'vertical', w); - // Bottom of the widget - if (overlap < 0.5) { - // Check if the ghost widget is not already below this widget - if (w.next() != dragWidget.ghost) { - w.parentNode.insertBefore(dragWidget.ghost, w.next()); - moved = true; - } - } - // Top of the widget - else { - // Check if the ghost widget is not already above this widget - if (w.previous() != dragWidget.ghost) { - w.parentNode.insertBefore(dragWidget.ghost, w); - moved = true; - } - } - found = true; - break; - } - } - // Not found a widget - if (! found) { - // Check if dropon has ghost widget - if (dragWidget.ghost.parentNode != dropon) { - // Get last widget bottom value - var last = dropon.immediateDescendants().last(); - var yLast = last ? Position.cumulativeOffset(last)[1] + last.getHeight() : 0; - if (y > yLast && last != dragWidget.ghost) { - dropon.appendChild(dragWidget.ghost); - moved = true; - } - } - } - if (moved && this.options.onChange) - this.options.onChange(this) - - this._updateColumnsHeight(); - }, - - // PRIVATE FUNCTIONS - _updateColumnsHeight: function() { - var h = 0; - this._columns.each(function(col) { - h = Math.max(h, col.immediateDescendants().inject(0, function(sum, element) { - return sum + element.getHeight(); - })); - }) - this._columns.invoke("setStyle", {height: h + 'px'}) - }, - - _clearTimer: function() { - if (this._outTimer) { - clearTimeout(this._outTimer); - this._outTimer = null; - } - } -}); diff --git a/drag_n_drop_portal/js/portal_edit.js b/drag_n_drop_portal/js/portal_edit.js deleted file mode 100644 index f664f2fe0..000000000 --- a/drag_n_drop_portal/js/portal_edit.js +++ /dev/null @@ -1,204 +0,0 @@ - -var _widgets_blocks = new Array(); -var _layout_params = new Array(); - -function onOverWidget(portal, widget) { - widget.getElement().insertBefore($('control_buttons'), widget.getElement().firstChild); - $('control_buttons').show(); -} - -function onOutWidget(portal, widget) { - $('control_buttons').hide(); -} - -function minimizeWidget(element) { - var widget = $(element).up(".widget").widget; - id = widget._getId().substr(7); - if ($('content_widget_' + id).style.display == 'none') { - $('content_widget_' + id).style.display = 'block'; - element.id = 'minimize_button'; - } else { - $('content_widget_' + id).style.display = 'none'; - element.id = 'maximize_button'; - } -} - -function removeWidget(element) { - var widget = $(element).up(".widget").widget; - - if (confirm(confirm_remove)) { - document.body.appendChild($('control_buttons').hide()) - portal.remove(widget); - } -} - -function listWidgets() { - - RedBox.loading(); - - // load edit options - new Ajax.Request(list_url, { - method: 'get', - onSuccess: function(transport) { - RedBox.showHtml('
' + transport.responseText + '
'); - }, - onFailure: function(transport) { - RedBox.close(); - } - }); -} - -function addWidget() { - - // Add widget - select = $('block_selection'); - title = select.options[select.selectedIndex].text; - - widget = new Xilinus.Widget(); - widget.setTitle(title); - widget.setContent(title); - portal.add(widget, parseInt($F('block_column'))); - - _widgets_blocks[_widgets_blocks.length] = select.value; - _layout_params[_widgets_blocks.length] = new Array(); - - // Edit wiget - editWidget(widget); - - cancelRedBox(); -} - -function reloadWidget(element) { - - if ($(element).id == 'reload_button') { - var widget = $(element).up(".widget").widget; - } else { - var widget = element; - } - - var id = widget._getId().substr(7); - - new Ajax.Request(load_url, { - parameters: getAjaxParameters(element), - method: 'get', - onSuccess: function(transport) { - block_data = transport.responseText.evalJSON(true); - widget.setTitle(block_data['title']); - widget.setContent(block_data['content']); - _widgets_blocks[widget._getId().substr(7)] = block_used; - }, - onFailure: function(transport) { - alert('Someting gone wrong.'); - } - }); -} - -function editWidget(element) { - - if ($(element).id == 'reload_button') { - var widget = $(element).up(".widget").widget; - } else { - var widget = element; - } - - new Ajax.Request(edit_url, { - parameters: getAjaxParameters(element), - method: 'get', - onSuccess: function(transport) { - RedBox.showHtml('
' + transport.responseText + '
'); - }, - onFailure: function(transport) { - RedBox.close(); - } - }); - -} - -function getAjaxParameters(element) { - - if ($(element).id == 'reload_button' || $(element).id == 'edit_button') { - var widget = $(element).up(".widget").widget; - } else { - var widget = element; - } - - var id = widget._getId().substr(7); - - parameters = 'block=' + _widgets_blocks[id]; - parameters = parameters + '&widget=' + widget._getId(); - - p = _layout_params[id]; - for (a in p) { - if (typeof(p[a]) != 'string') { - break; - } - parameters = parameters + '&defaults[' + a + ']=' + p[a]; - } - - return parameters; -} - -function setParams() { - - widget_name = ''; - params = new Array(); - inputs = $('blockform').getElements(); - inputs.each(function(item) { - name = item.name.substr(0, 6); - if (name == 'params') { - pos = item.name.indexOf(']', 7); - param_name = item.name.substr(7, pos - 7); - if (item.type == 'checkbox') { - params[param_name] = item.checked; - } else { - params[param_name] = item.value; - } - } - if (name == 'widget') { - widget_name = item.value; - } - }); - - _layout_params[widget_name.substr(7)] = params; - - var widget = $(widget_name).widget; - reloadWidget(widget); - - cancelRedBox(); -} - -function noParams(widget_name, msg) { - - // alert(msg); - - var widget = $(widget_name).widget; - reloadWidget(widget); - - cancelRedBox(); -} - -function cancelRedBox() { - RedBox.close(); - return false; -} - -function savePortal() { - - parameters = portal.serialize(); - - for (var i = 0; i < _layout_params.length; i++) { - parameters = parameters + '¶ms[' + i + '][type]=' + _widgets_blocks[i]; - p = _layout_params[i]; - for (a in p) { - if (typeof(p[a]) != 'string') { - break; - } - parameters = parameters + '¶ms[' + i + '][' + a + ']=' + p[a]; - } - } - - new Ajax.Request(save_url, { - parameters: parameters, - method: 'post' - }); -} diff --git a/drag_n_drop_portal/lib/Block/Layout/View/js.php b/drag_n_drop_portal/lib/Block/Layout/View/js.php deleted file mode 100644 index a42287da6..000000000 --- a/drag_n_drop_portal/lib/Block/Layout/View/js.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @package Horde_Block - */ -class Horde_Block_Layout_View_Js extends Horde_Block_Layout_View { - - /** - * Render the current layout as HTML. - * - * @return string HTML layout. - */ - function toHtml() - { - $html = '
'; - $js = ''; - - $js_init .= 'portal.addWidgetControls("control_buttons");' - . '}' - . 'document.observe("dom:loaded", init); -' - . ''; - - $html .= '
' . "\n" . $js . "\n" . $js_init; - - // Strip any CSS tags out of the returned content so - // they can be handled seperately. - if (preg_match_all('//', $html, $links)) { - $html = str_replace($links[0], '', $html); - $this->_linkTags = $links[0]; - } - - return $html; - } - - function _serializeBlock($js_id, $app, $name, $params, &$js_init, $col_num) - { - $block = Horde_Block_Collection::getBlock($app, $name, $params); - if ($block instanceof PEAR_Error) { - $title = $block->getMessage(); - $content = $block->getDebugInfo(); - $params = array(); - } else { - $content = @$block->getContent(); - if ($content instanceof PEAR_Error) { - $content = $content->getDebugInfo(); - } - $title = @$block->getTitle(); - if ($title instanceof PEAR_Error) { - $title = $title->getMessage(); - } else { - $title = strip_tags($title); - } - } - - $content = Horde_Serialize::serialize($content, Horde_Serialize::JSON, $GLOBALS['registry']->getCharset()); - $title = Horde_Serialize::serialize($title, Horde_Serialize::JSON, $GLOBALS['registry']->getCharset()); - $params = Horde_Serialize::serialize($params, Horde_Serialize::JSON, $GLOBALS['registry']->getCharset()); - - $js_init .= 'portal.add(new Xilinus.Widget().' - . 'setTitle(title_' . $js_id .').' - . ' setContent(content_' . $js_id .'), ' . $col_num . ');' - . '_widgets_blocks[' . $js_id . '] = "' . $app . ':' . $name . '";' - . '_layout_params[' . $js_id . '] = \'' . $params . '\'.evalJSON();' - . 'delete title_' . $js_id .';' - . 'delete content_' . $js_id .';' . "\n"; - - return 'var content_' . $js_id . ' = ' . $content . ';' . "\n" - . 'var title_' . $js_id . ' = ' . $title . ';' . "\n"; - } -} diff --git a/drag_n_drop_portal/params.php b/drag_n_drop_portal/params.php deleted file mode 100644 index bd6c2e146..000000000 --- a/drag_n_drop_portal/params.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @package Folks - */ -define('HORDE_BASE', dirname(__FILE__) . '/..'); -require_once HORDE_BASE . '/lib/base.php'; -require_once 'Horde/Loader.php'; - -// Block to load -$block_id = Horde_Util::getFormData('block'); -list($app, $name) = explode(':', $block_id); - -// Load collection -$blocks = new Horde_Block_Collection(null, array($app)); - -// Create block params form -$params = $blocks->getParams($app, $name); -if (empty($params) || - !$blocks->isEditable($app, $name)) { - echo ''; -} else { - $block = &$blocks->getBlock($app, $name); - - $defaults = Horde_Util::getFormData('defaults'); - if (empty($defaults)) { - foreach ($params as $key => $val) { - $defaults[$key] = $val; - } - } - if (!isset($defaults['_refresh_time'])) { - $defaults['_refresh_time'] = 0; - } - require './templates/portal/params.php'; -} diff --git a/drag_n_drop_portal/save.php b/drag_n_drop_portal/save.php deleted file mode 100644 index 08baf62c8..000000000 --- a/drag_n_drop_portal/save.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @package Folks - */ -require_once dirname(__FILE__) . '/../lib/base.php'; - -$layout = array(); -$params = Horde_Util::getPost('params'); -foreach ($_POST as $column => $rows) { - if (substr($column, 0, 11) != 'widget_col_') { - continue; - } - $col = (int)substr($column, 11); - foreach ($rows as $row => $widget) { - $id = (int)substr($widget, 7); - list($app, $name) = explode(':', $params[$id]['type']); - $layout[$row][$col] = array('app' => $app, - 'height' => 1, - 'width' => 1, - 'params' => array('type' => $name, - 'params' => $params[$id])); - } -} - -$prefs->setValue('portal_layout', serialize($layout)); diff --git a/drag_n_drop_portal/select.php b/drag_n_drop_portal/select.php deleted file mode 100644 index 855f69686..000000000 --- a/drag_n_drop_portal/select.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @package Folks - */ -define('HORDE_BASE', dirname(__FILE__) . '/..'); -require_once HORDE_BASE . '/lib/base.php'; -require_once 'Horde/Loader.php'; - -?> - - -
- -
-" onclick="return addWidget()" /> -" onclick="return cancelRedBox()" /> - diff --git a/drag_n_drop_portal/templates/portal/params.php b/drag_n_drop_portal/templates/portal/params.php deleted file mode 100644 index 0ffcbcdb8..000000000 --- a/drag_n_drop_portal/templates/portal/params.php +++ /dev/null @@ -1,37 +0,0 @@ -

getName($app, $name)) ?>

-
- - - - - -updateable): ?> - - - - - - - - - - - - - - -
  - -
getParamName($app, $name, $id) ?>: getOptionsWidget($app, $name, $id, $defaults) ?>
-" onclick="return setParams()" /> -" onclick="return cancelRedBox()" /> -
-
diff --git a/drag_n_drop_portal/themes/graphics/bottom_left.gif b/drag_n_drop_portal/themes/graphics/bottom_left.gif deleted file mode 100644 index d324686e3694c71603b4f37731a60829effae420..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmZ?wbhEHb+|z`(+w1LA)2Td#JcUSBy^=p-Mr_W5Ea25SH-86FJ) diff --git a/drag_n_drop_portal/themes/graphics/bottom_right.gif b/drag_n_drop_portal/themes/graphics/bottom_right.gif deleted file mode 100644 index 930a8cf0c08d6d0c087bffbb58a2a4be9884899c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339 zcmV-Z0j&N}*y*TU5yZ>M)j$~<`XsWJk>%MR-&ona-I9~63@BhG{ za7Zi~kI1BQdAj8Y%&2rqty-_xtai)ocAPn{cuX#v&*-#z&9*(E?YMkSuiNkV{1L3v z`~QG}f`f#GQ+#lSii?bmj*pOjh>?_)mY0~Bnl6)@o}ZwhqN9O`iKM8hs;jK6K&Gdz zva__cwzseZ1G~JvzQ4f1!o$SH#>dFX%FE2n&d<=%($mz{*4NnC+S}aS-rwNi;^XAy zxo_y{>g(+7?(gvN^7Hid_V@Vt`uqI-{{H|23LHqVpuvL(6DnNDu%W|;5F<*QNU@^D lix@L%+{m#QqsNaRLy8 zPe@vE9DlyKiM^~2VI#Ihe^-HNorkeY zGxx+~dVM-Rt~;HW&>=?+y?+kGgF(^fj*d5WnQYtF)I^_mcBTT|-Kj4c4Q-dpx6#AQ zUkBnB7mr(e-8vdhrq zBrvnHz*sC0U0p>W=QZ>&gIVmP2Vx!%by!uk9_Z--W_lWKx3(bZa6oi!jz`kzM2+_X zy}fWKm#f2~z*m#0 z!KYNxtkDSU;2n3w^5y*KBJn9EU**Wpw;g9>+?`Pr zTuLN7kfVkkW-yx`h{a+=AP^uv?e7adS}f#ywYuD#nQ2-Vi}yCf;vfR~2Z}PiYiumH z&diY8J39iu-%l_MLlA3gYXYrS`=qp_BugTZNQENNvrM6|^eIWcDj`V?2W=inDmm>X z=RKz=DzBiRAX}|gi>y|wfQUpQgw19Xn9b%#!^6X(p`oD+!@z)~-(bjktJmis`t|y3 s19#>;%4jr-rlzKZySuxBP$)$F1gsl`3Ib%REdT%j07*qoM6N<$f=?)9OaK4? diff --git a/drag_n_drop_portal/themes/graphics/edit.png b/drag_n_drop_portal/themes/graphics/edit.png deleted file mode 100644 index 83c9fe47092900c43d37612090bf3e7e383a2c06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmV;y0zUnTP)h!5p(7uvikUHjE%#gTEy_VsbnOT^d{RsCS+5-fI z!XkD8I-OqNcDucP{|A_QM}o~oLhDc*M7lm33h&BFW-_UTPN(y2IJ5wZsOpdU9)u3n z8|IE(e-E<37}Q+6)4MIXsHliNIx;#nKmR>lsOjnH-z-+)X%sq46?6r8dJ>5&!YO4} zcLtfoVwI32ITwjU@iV2XjT)%^e@XYBq}AMvV-e}|D3r@C={DVYY;5e4R(s)z)oOi{ zOeUeBp&|2>yaFMu_I8qggM^lW1t>kE(5C$wjpp*o$_k+Qn%C={K|Sznt%)*0VVuqaqPS|{F(w19Ow%wk;@4?nH&$gX?cHr`hsoQUFIrDV;xo5jCKHqck`Tzg_WoKCg z01Xi?3GxdDa?t?8rrJ9kKxsWs7sn8ZsmTIP%seJS2@XsGjB<>QbqWujCAD#V_*k@I m^G2hM21P~**PYm>Gcg#2@~8j${jM6Qlfl!~&t;ucLK6T0fn84k diff --git a/drag_n_drop_portal/themes/graphics/plus.png b/drag_n_drop_portal/themes/graphics/plus.png deleted file mode 100644 index 263e356901817a5ace857c6416481a8cc89faedc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Wq?nJt4ZpT+GW?9SKZil=2`uU z>uqaqPS|{F(w19Ow%wk;@4?nH&$gX?cHr`hsoQUFIrDV;xo5jCKHqck`Tzg_WoKCg z01Xi?3GxdDa?t?8rrJ9kKxq$87sn8Z%gF*x%sdt>5)BNY4fE%VFixnOz;HxH;E|xf z6LzLNy|fh!^7`!7(%Qn@%IeHc+}hes+(!b!N}?k;cQW67Sy98yP|(Hueogq5a-f+E Mp00i_>zopr0454z8UO$Q diff --git a/drag_n_drop_portal/themes/graphics/reload.png b/drag_n_drop_portal/themes/graphics/reload.png deleted file mode 100644 index dcb020450dd0bfe53e5a9bd3c80e656ffb5d9e80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264 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 P-+#0&1P{j=JSFWfMw#+h diff --git a/drag_n_drop_portal/themes/graphics/top_left.gif b/drag_n_drop_portal/themes/graphics/top_left.gif deleted file mode 100644 index dd665b90b69445c3f2ddb9a6e665323aa250a45b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 zcmZ?wbhEHbIv|}OGZm<5?pE2B2O z^V(W?^~k4^$Is7v-!w;CS^(GWV9rPOGVCD?J;@RaS0_MYq; qITCuO*qav`gsgea+SEHS;W;O>8FylF19PJ>S79YH6EmYAgEau-C|x7~ diff --git a/drag_n_drop_portal/themes/graphics/top_right.gif b/drag_n_drop_portal/themes/graphics/top_right.gif deleted file mode 100644 index e46ca3930566b5520c1ef2dda7c5d2d6e92e95e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1123 zcmV-p1f2UvNk%w1Vdw)N0J8u900030|Ns8}{{8*^{QUg;`}_L(`uX|!`1ttu_xJYp z_VxAk^z`((xw-%U{{R30A^8LW000gEEC2ui0O$iB000F4(8)=wy*TU5yZ>M)j$~<` zXsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ$!t2G(5Q4uty-_xtai)odcWYXcuX#v z&*-#z&2GEj@VIsu}^UuCK7Mva__cwzs&sy1Tr+zQ4f1!o$SH#>dFX%FE2n&d<=% z($mz{*4BX-*W29P-rwNi;^XAy=I7|?>g(Kq7wquy^7Hid_V@Vt`uqIM?iKw43LHqV zpuvL(6DnM&tAPcE5F<*QNU@^Dix}(un~<@i$B!WYLy8f9z%!p@&Sg9;r=v}I2RMUyIB%CxCdct@W~ol3Q;)vLLVGT6$stJkk! z!-^eCwyfE+Xw#})%eJlCw{YXiolCc_-Me`6>fOt?uiw9b0}CEZ7%;7)3lb|{%($`R z$B-jSo=my2<;$2eYu?Pcv**vCLyI0wy0q!js8g$6&APSg*RW&De!Vr;Q3bej>)y?~ zx9{J;g9{%{ytwh>$dfBy&b+zv=g^}|pH98H_3PNPYv0bjyZ7(l!+TH60M^k2=+moT z&%V9;_weJ(pHIKO{rmXy>)+46zyJRL1}NbFfCLt3;DHDxsNjMOHt67k5Ju=AZVQy> z%25bpsNsejcIe@UAciR7h$NP1;)y7xsN#w&w&>!EFvck3j5OA0ydtsG^* zq?A@_>7|%vs_CYjcIxS;poS{ysHB!^>Zz!vs_Lq&w(9Duu*NFuthCl@>#exvs_U-2 z=DMV#3Y2$L0mK$-?6JrutL(DOHtX#Fv(QE>?X=WZYwfkzW~=SC+;;2jx8Q~=?zrTZ zYwo$|rmOC{?6#}!q)Ivp=}`pKYwx}I=Bw|%{PyebzW@g;@W2EYZ1BMdC#>+o3^(lX z!w^R-@x&BYZ1KeyXRPtY9Cz&T#>5&BuL1!aHNeRzr>yeIEVu0P%P_|*^UO5YZ1c@H z=dAP2JooJL&p-z)^w2~XZS>JdC$03-OgHWH(@-~EZvi47kN^Wm383}XTzBpD*I*wdY`5+9+i=G%_uO>XZTH=H=dJhNeE045-+%`$_~3t|OaRpfAh1Bz pgg5T^s=D{xc<06RAkoQ41Z diff --git a/drag_n_drop_portal/themes/screen.css b/drag_n_drop_portal/themes/screen.css deleted file mode 100644 index c4f3274fb..000000000 --- a/drag_n_drop_portal/themes/screen.css +++ /dev/null @@ -1,217 +0,0 @@ - -/* Redbox styles. */ -#RB_overlay { - position: absolute; - z-index: 100; - width: 100%; - height: 100%; - top: 0; - left: 0; - right: 0; - bottom: 0; - min-height: 100%; - background-color: #000; - opacity: .6; - filter: alpha(opacity=60); -} -#RB_loading { - z-index: 101; - width: 66; - margin-left: auto; - margin-right: auto; - margin-top: 200px; - padding-bottom: 66px; - text-align: center; - background: url("graphics/redbox_spinner.gif") no-repeat bottom center; -} -#RB_window { - z-index: 102; - background-color: #fff; - display: block; - text-align: left; - overflow: hidden; - margin: 20px auto 0 auto; - position: absolute; -} - -#RB_confirm { - width: 20em; - padding: 1em; - border: 1px solid #ccc; - background: #ffc; -} -#RB_confirm input { - margin: .2em; -} - -#RB_info { - width: 30em; - padding: 1em; - border: 1px solid #ccc; - background: #ccf; -} -#RB_info input { - margin: .2em; -} - -/* Portal editing */ - -#page { - margin: 10px auto; -} - -#page1 { - float: left; - width: 45%; -} - -#page2 { - float: right; - width: 45%; -} - -#widget_col_0 { - float: left; - width: 30%; - background: #E6E6E6; -} - -#widget_col_1 { - width: 50%; - float: left; - background: #CCC; -} - -#widget_col_2 { - float: left; - width: 20%; - background: #B3B3B3; -} - -#widget_col_3 { - float: left; - width: 40%; - background: #B3B3B3; -} - -#widget_col_4 { - float: left; - width: 60%; - background: #E6E6E6; -} - -#control_buttons { - position: absolute; - right: 0px; - top: 10px; - width: 90px; -} - -#reload_button { - position: relative; - float: left; - width: 16px; - height: 16px; - background: url(graphics/reload.png); - behavior: url(png.htc); - margin-right: 5px; -} - -#minimize_button { - position: relative; - float: left; - width: 16px; - height: 16px; - background: url(graphics/minus.png); - behavior: url(png.htc); - margin-right: 5px; -} - -#maximize_button { - position: relative; - float: left; - width: 16px; - height: 16px; - background: url(graphics/plus.png); - behavior: url(png.htc); - margin-right: 5px; -} - -#edit_button { - position: relative; - float: left; - width: 16px; - height: 16px; - background: url(graphics/edit.png); - behavior: url(png.htc); - margin-right: 5px; -} - -#delete_button { - position: relative; - float: left; - width: 16px; - height: 16px; - background: url(graphics/delete.png); - behavior: url(png.htc); - margin-right: 5px; -} - -/* Sliding doors technique */ -.widget_nw { - background: transparent url(graphics/top_left.gif) no-repeat; - height: 30px; -} - -.widget_w { - border-left: 1px solid #B9B9B9; - margin-left: 5px; -} - -.widget_sw { - background: transparent url(graphics/bottom_left.gif) no-repeat; - height: 15px; -} - -.widget_title { - background: url(graphics/top_right.gif) repeat-x right top; - color: #123456; - font: bold 14px/25px Tahoma, Arial, sans-serif; - height: 26px; - margin: 0 0 0 15px; - padding: 5px 0 0 0 ; - text-align: center; - margin-left: 15px; -} - -.widget_content { - background-color: #FDFDFD; - color: #71777A; - font: normal 12px/1em Tahoma, Arial, sans-serif; - overflow: hidden; - padding: 5px; - border-right: 1px solid #B9B9B9; - margin-right: 5px; -} - -.widget_statusbar { - background: transparent url(graphics/bottom_right.gif) repeat-x right top; - font-size: 8px; - height: 15px; - margin-left: 11px; -} - -.widget_draggable { - cursor: move; -} - -/* Ghost */ -.widget_ghost { - background: #FFF; - opacity: 0.5; - filter: alpha(opacity=50); - position: relative; - border: 3px dashed #F00; - margin: 0px; - padding: 0; -} diff --git a/fima/COPYING b/fima/COPYING deleted file mode 100644 index 5a965fbc5..000000000 --- a/fima/COPYING +++ /dev/null @@ -1,280 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 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. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -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 Program or any portion -of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -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 Program, 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 Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) 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; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, 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 executable. However, as a -special exception, the source code 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. - -If distribution of executable or 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 counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program 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. - - 5. 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 Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program 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 to -this License. - - 7. 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 Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program 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 Program. - -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. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program 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. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 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 Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, 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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. 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 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. - - END OF TERMS AND CONDITIONS diff --git a/fima/README b/fima/README deleted file mode 100644 index af2412ca4..000000000 --- a/fima/README +++ /dev/null @@ -1,85 +0,0 @@ -What is Fima? -================= - -.. contents:: Contents -.. section-numbering:: - -Fima is a double entry based ledger written in PHP and utilizing the Horde -Application Framework. - -This software is OSI Certified Open Source Software. OSI Certified is a -certification mark of the `Open Source Initiative`_. - -.. _`Open Source Initiative`: http://www.opensource.org/ - - -Obtaining Fima ------------------- - -Further information on Fima and the latest version can be obtained at - - http://www.horde.org/fima/ - - -Documentation -------------- - -The following documentation is available in the Fima distribution: - -:README_: This file -:COPYING_: Copyright and license information -:LICENSE_: Copyright and license information -:`docs/CHANGES`_: Changes by release -:`docs/CREDITS`_: Project developers -:`docs/INSTALL`_: Installation instructions and notes -:`docs/TODO`_: Development TODO list -:`docs/UPGRADING`_: Pointers on upgrading from previous Fima versions - - -Installation ------------- - -Instructions for installing Fima can be found in the file INSTALL_ in the -``docs/`` directory of the Fima distribution. - - -Assistance ----------- - -If you encounter problems with Fima, help is available! - -The Horde Frequently Asked Questions List (FAQ), available on the Web at - - http://www.horde.org/faq/ - -The Horde Project runs a number of mailing lists, for individual applications -and for issues relating to the project as a whole. Information, archives, and -subscription information can be found at - - http://www.horde.org/mail/ - -Lastly, Horde developers, contributors and users also make occasional -appearances on IRC, on the channel #horde on the freenode Network -(irc.freenode.net). - - -Licensing ---------- - -For licensing and copyright information, please see the file COPYING_/LICENSE_ -in the Fima distribution. - -Thanks, - -The Fima team - - -.. _README: ?f=README.html -.. _COPYING: http://www.horde.org/licenses/gpl.php -.. _LICENSE: http://www.horde.org/licenses/asl.php -.. _docs/CHANGES: ?f=CHANGES.html -.. _docs/CREDITS: ?f=CREDITS.html -.. _INSTALL: -.. _docs/INSTALL: ?f=INSTALL.html -.. _docs/TODO: ?f=TODO.html -.. _docs/UPGRADING: ?f=UPGRADING.html diff --git a/fima/account.php b/fima/account.php deleted file mode 100644 index 78cb7be7c..000000000 --- a/fima/account.php +++ /dev/null @@ -1,229 +0,0 @@ - - * - * See the enclosed file COPYING for license information (GPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. - */ - -@define('FIMA_BASE', dirname(__FILE__)); -require_once FIMA_BASE . '/lib/base.php'; -require_once FIMA_BASE . '/lib/Forms/account.php'; -$vars = Horde_Variables::getDefaultVariables(); - -/* Redirect to the account list if no action has been requested. */ -$actionID = $vars->get('actionID'); -if (is_null($actionID)) { - Horde::url('accounts.php', true)->redirect(); -} - -/* Get ledger. */ -$ledger = Fima::getActiveLedger(); -$share = &$GLOBALS['fima_shares']->getShare($ledger); -if (is_a($share, 'PEAR_Error')) { - $notification->push(sprintf(_("Access denied on account: %s"), $share->getMessage()), 'horde.error'); - Horde::url('accounts.php', true)->redirect(); -} -$ledger_name = $share->get('name'); - -/* Run through the action handlers. */ -switch ($actionID) { -case 'add_account': - $vars->set('actionID', 'save_account'); - - /* Preset account attributes regarding its parent. */ - $parent_id = $vars->get('account'); - $vars->set('parent_id', $parent_id); - if (isset($parent_id)) { - $account_types = Fima::getAccountTypes(); - if (isset($account_types[$parent_id])) { - $vars->set('type', $parent_id); - } else { - $parent = Fima::getAccount($parent_id); - if (!is_a($parent, 'PEAR_Error')) { - if (Fima::getAccountParent($parent['number']) === null) { - $accounts = Fima::listAccounts(); - $tmp = ''; - foreach ($accounts as $accountId => $account) { - if ((int)$account['number'] >= $parent['number'] + 100) { - break; - } - $tmp = $account['number'] + 1; - } - if (Fima::getAccountParent($tmp) == $parent['number']) { - $vars->set('number', sprintf('%\'04d', $tmp)); - } - } - $vars->set('type', $parent['type']); - } - } - } - $vars->set('number_new', $vars->get('number')); - - $form = new Fima_AccountForm($vars, _("New Account")); - break; - -case 'modify_account': - $account_id = $vars->get('account'); - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) { - $notification->push(_("Access denied editing account."), 'horde.error'); - } else { - $account = Fima::getAccount($account_id); - if (!isset($account) || !isset($account['account_id'])) { - $notification->push(_("Account not found."), 'horde.error'); - } else { - $vars = new Horde_Variables($account); - $vars->set('actionID', 'save_account'); - $vars->set('number_new', $vars->get('number')); - $form = new Fima_AccountForm($vars, sprintf(_("Edit: %s"), trim($account['number'] . ' ' . $account['name'])), $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)); - break; - } - } - - /* Return to the accounts. */ - Horde::url('accounts.php', true)->redirect(); - -case 'save_account': - if ($vars->get('submitbutton') == _("Delete this account")) { - /* Redirect to the delete form. */ - $account_id = $vars->get('account_id'); - header('Location: ' . Horde_Util::addParameter(Horde::url('account.php', true), array('account' => $account_id, 'actionID' => 'delete_account'), null, false)); - exit; - } - - $form = new Fima_AccountForm($vars, $vars->get('account_id') ? sprintf(_("Edit: %s"), $vars->get('name')) : _("New Account")); - if (!$form->validate($vars)) { - break; - } - - $form->getInfo($vars, $info); - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) { - $notification->push(sprintf(_("Access denied saving account to %s."), $share->get('name')), 'horde.error'); - Horde::url('accounts.php', true)->redirect(); - } - - $storage = &Fima_Driver::singleton($ledger); - $info['number_new'] = sprintf('%\'04d', $info['number_new']); - - /* Check for existing account width provided number. */ - if ($info['number'] != $info['number_new']) { - $existingaccount = $storage->getAccountByNumber($info['number_new']); - if (!is_a($existingaccount, 'PEAR_Error')) { - $notification->push(sprintf(_("The account number %s is already used by the account %s."), $info['number_new'], trim($existingaccount['number'] . ' ' . $existingaccount['name'])), 'horde.error'); - break; - } else { - $notification->push(sprintf(_("The account including all postings was shifted from number %s to %s."), $info['number'], $info['number_new']), 'horde.message'); - } - } - - /* Check account type. */ - if (($parent_number = Fima::getAccountParent($info['number_new'])) !== null) { - $parent = $storage->getAccountByNumber($parent_number); - if (!is_a($parent, 'PEAR_Error')) { - if ($info['type'] != $parent['type']) { - $info['type'] = $parent['type']; - $notification->push(sprintf(_("The account type was set to %s."), Fima::getAccountTypes($info['type'])), 'horde.message'); - } - } - } - - /* If an account id is set, we're modifying an existing account. - * Otherwise, we're adding a new account with the provided - * attributes. */ - if (!empty($info['account_id'])) { - $result = $storage->modifyAccount($info['account_id'], - $info['number_new'], - $info['type'], - $info['name'], - $info['eo'], - $info['desc'], - $info['closed']); - } else { - $result = $storage->addAccount($info['number_new'], - $info['type'], - $info['name'], - $info['eo'], - $info['desc'], - $info['closed']); - } - - /* Check our results. */ - if (is_a($result, 'PEAR_Error')) { - $notification->push(sprintf(_("There was a problem saving the account: %s."), $result->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("Saved %s."), trim($info['number_new'] . ' ' . $info['name'])), 'horde.success'); - /* Return to the accounts. */ - if ($vars->get('submitbutton') == _("Save and New")) { - header('Location: ' . Horde_Util::addParameter(Horde::url('account.php', true), array('account' => $vars->get('parent_id'), 'actionID' => 'add_account'), null, false)); - exit; - } - Horde::url('accounts.php', true)->redirect(); - } - - break; - -case 'delete_account': - $account_id = $vars->get('account'); - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)) { - $notification->push(_("Access denied deleting account."), 'horde.error'); - } else { - $account = Fima::getAccount($account_id); - if (!isset($account) || !isset($account['account_id'])) { - $notification->push(_("Account not found."), 'horde.error'); - } else { - $vars = new Horde_Variables($account); - $vars->set('actionID', 'purge_account'); - $vars->set('dssubaccounts', array('type' => 'none', 'account' => $account_id)); - $vars->set('dspostings', array('type' => 'delete', 'account' => $account_id)); - $form = new Fima_AccountDeleteForm($vars, sprintf(_("Delete: %s"), trim($account['number'] . ' ' . $account['name'])), $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)); - break; - } - } - - /* Return to the accounts. */ - Horde::url('accounts.php', true)->redirect(); - -case 'purge_account': - if ($vars->get('submitbutton') == _("Edit this account")) { - /* Redirect to the edit form. */ - $account_id = $vars->get('account_id'); - header('Location: ' . Horde_Util::addParameter(Horde::url('account.php', true), array('account' => $account_id, 'actionID' => 'modify_account'), null, false)); - exit; - } - - $form = new Fima_AccountDeleteForm($vars, sprintf(_("Delete: %s"), trim($vars->get('number') . ' ' . $vars->get('name')))); - if (!$form->validate($vars)) { - break; - } - - $form->getInfo($vars, $info); - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)) { - $notification->push(sprintf(_("Access denied deleting account from %s."), $share->get('name')), 'horde.error'); - Horde::url('accounts.php', true)->redirect(); - } - - $storage = &Fima_Driver::singleton($ledger); - - /* Delete the account. */ - $result = $storage->deleteAccount($info['account_id'], $info['dssubaccounts'], $info['dspostings']); - - /* Check our results. */ - if (is_a($result, 'PEAR_Error')) { - $notification->push(sprintf(_("There was a problem deleting the account: %s."), $result->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("Deleted %s."), trim($info['number_new'] . ' ' . $info['name'])), 'horde.success'); - /* Return to the accounts. */ - Horde::url('accounts.php', true)->redirect(); - } - - break; - -default: - Horde::url('accounts.php', true)->redirect(); -} - -$title = $form->getTitle(); -require FIMA_TEMPLATES . '/common-header.inc'; -require FIMA_TEMPLATES . '/menu.inc'; -$form->renderActive(); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/fima/accounts.php b/fima/accounts.php deleted file mode 100644 index b4d019857..000000000 --- a/fima/accounts.php +++ /dev/null @@ -1,98 +0,0 @@ - - * - * See the enclosed file COPYING for license information (GPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. - * - * @author Thomas Trethan - */ - -@define('FIMA_BASE', dirname(__FILE__)); -require_once FIMA_BASE . '/lib/base.php'; -require_once 'Horde/Tree.php'; - -/* Get ledger. */ -$ledger = Fima::getActiveLedger(); -$share = &$GLOBALS['fima_shares']->getShare($ledger); -if (is_a($share, 'PEAR_Error')) { - $notification->push(sprintf(_("Access denied on accounts: %s"), $share->getMessage()), 'horde.error'); -} - -/* Run through the action handlers. */ -$actionID = Horde_Util::getFormData('actionID'); -switch ($actionID) { -case 'delete_all': - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)) { - $notification->push(_("Access denied deleting all accounts and postings."), 'horde.error'); - } else { - $storage = &Fima_Driver::singleton($ledger); - - /* Delete all. */ - $result = $storage->deleteAll(); - if (is_a($result, 'PEAR_Error')) { - $notification->push(sprintf(_("There was a problem deleting all accounts and postings: %s"), - $result->getMessage()), 'horde.error'); - } else { - $notification->push(_("Deleted all accounts and postings."), 'horde.success'); - } - break; - } -default: - break; -} - -/* Prepare account folder structure */ -$account_url = Horde::url('account.php');; -$view_url = Horde_Util::addParameter(Horde::url('postings.php'), 'actionID', 'search_postings'); - -$accounts = array(); -$accounts['root'] = array('account_id' => 'root', 'owner' => $ledger, 'number' => '', 'type' => 'root', 'name' => $share->get('name'), 'desc' => '', 'icon' => 'accounts.png', 'closed' => false, 'expanded' => true, 'parent_id' => null); - -$types = Fima::getAccountTypes(); -foreach ($types as $typeId => $typeLabel) { - $accounts[$typeId] = array('account_id' => $typeId, 'owner' => $ledger, 'number' => '', 'type' => $typeId, 'name' => $typeLabel, 'desc' => '', 'icon' => $typeId . '.png', 'closed' => false, 'expanded' => true, 'parent_id' => 'root', 'view_link' => Horde_Util::addParameter($view_url, 'search_type', $typeId), 'add_link' => Horde_Util::addParameter($account_url, array('account' => $typeId, 'actionID' => 'add_account'))); -} - -/* Get accounts. */ -$accountlist = Fima::listAccounts(); -foreach ($accountlist as $accountId => $account) { - $accounts[$accountId] = $account; - - $accounts[$accountId]['view_link'] = Horde_Util::addParameter($view_url, $account['type'] == FIMA_ACCOUNTTYPE_ASSET ? 'search_asset' : 'search_account', $account['account_id']); - $account_url_account = Horde_Util::addParameter($account_url, 'account', $account['account_id']); - $accounts[$accountId]['add_link'] = Horde_Util::addParameter($account_url_account, 'actionID', 'add_account'); - $accounts[$accountId]['edit_link'] = Horde_Util::addParameter($account_url_account, 'actionID', 'modify_account'); - $accounts[$accountId]['delete_link'] = Horde_Util::addParameter($account_url_account, 'actionID', 'delete_account'); - - if ($account['parent_id'] !== null && isset($accounts[$account['parent_id']])) { - unset($accounts[$accountId]['add_link']); - } else { - $accounts[$accountId]['parent_id'] = $account['type']; - $accounts[$accountId]['parent_number'] = ''; - $accounts[$accountId]['parent_name'] = ''; - } - - $accounts[$accountId]['icon'] = $accounts[$accounts[$accountId]['parent_id']]['icon']; - $accounts[$accountId]['closed'] = $account['closed']; - $accounts[$accountId]['expanded'] = false; -} - -/* Print. */ -$print_view = (bool)Horde_Util::getFormData('print'); -if (!$print_view) { - $print_link = Horde::url(Horde_Util::addParameter('accounts.php', array('print' => 1))); -} - -Horde::addScriptFile('tables.js', 'horde'); -$title = _("My Accounts"); -require FIMA_TEMPLATES . '/common-header.inc'; - -if ($print_view) { - require_once $registry->get('templates', 'horde') . '/javascript/print.js'; -} else { - require FIMA_TEMPLATES . '/menu.inc'; -} - -require FIMA_TEMPLATES . '/accounts/accounts.inc'; -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/fima/config/.htaccess b/fima/config/.htaccess deleted file mode 100644 index 3a4288278..000000000 --- a/fima/config/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/fima/config/conf.xml b/fima/config/conf.xml deleted file mode 100644 index 20f244646..000000000 --- a/fima/config/conf.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - Storage System Settings - - sql - - - - fima_accounts - fima_postings - - - - - - - - Menu Settings - - - - - - - diff --git a/fima/config/menu.php.dist b/fima/config/menu.php.dist deleted file mode 100644 index b03d82515..000000000 --- a/fima/config/menu.php.dist +++ /dev/null @@ -1,39 +0,0 @@ - 'http://www.example.com/', - * 'text' => 'Example, Inc.', - * 'icon' => 'example.png', - * 'icon_path' => 'http://www.example.com/images/', - * 'target' => '_blank', - * 'onclick' => '' - * ); - * - * You can also add a "separator" (a spacer) between menu items. To add a - * separator, simply add a new string to the $_menu array set to the text - * 'separator'. It should look like this: - * - * $_menu[] = 'separator'; - */ - -$_menu = array(); - -/* Add your custom entries below this line. */ diff --git a/fima/config/prefs.php.dist b/fima/config/prefs.php.dist deleted file mode 100644 index 8a06772d3..000000000 --- a/fima/config/prefs.php.dist +++ /dev/null @@ -1,168 +0,0 @@ - _("General Preferences"), - 'label' => _("Active Configuration"), - 'desc' => _("Choose your active Ledger and Posting Type."), - 'members' => array( - 'active_ledger', 'active_postingtype', 'closedperiodselect' - ) -); - -$prefGroups['display'] = array( - 'column' => _("General Preferences"), - 'label' => _("Interface Preferences"), - 'desc' => _("Change the display and input preferences."), - 'members' => array( - 'max_postings', 'startpage', 'sortby', 'altsortby', 'sortdir', - 'wildcard_format', 'amount_format', 'expenses_sign', 'delete_opt', - 'report_graphsize' - ) -); - -// active ledger -// Set locked to true if you don't want users to have multiple ledgers. -$_prefs['active_ledger'] = array( - 'value' => $GLOBALS['registry']->getAuth() ? $GLOBALS['registry']->getAuth() : 0 - 'type' => 'enum', - 'shared' => true -); - -// store the ledgers to diplay -$_prefs['display_ledgers'] = array( - 'value' => 'a:0:{}' -); - -// active posting type -$_prefs['active_postingtype'] = array( - 'value' => FIMA_POSTINGTYPE_ACTUAL, - 'type' => 'enum', - 'enum' => array( - FIMA_POSTINGTYPE_ACTUAL => _("Actual"), - FIMA_POSTINGTYPE_FORECAST => _("Forecast"), - FIMA_POSTINGTYPE_BUDGET => _("Budget") - ), - 'desc' => _("Your active posting type:") -); - -// closed period selection widget -$_prefs['closedperiodselect'] = array( - 'type' => 'special' -); - -// closed period -$_prefs['closed_period'] = array( - 'value' => 0 -); - -// postings per page -$_prefs['max_postings'] = array( - 'value' => 20, - 'type' => 'number', - 'desc' => _("Postings per page in the list view.") -); - -// start page -$_prefs['startpage'] = array( - 'value' => -1, - 'type' => 'enum', - 'enum' => array( - 1 => _("First Page"), - -1 => _("Last Page") - ), - 'desc' => _("When displaying the postings, which page do you want to start on?") -); - -// user preferred sorting column -$_prefs['sortby'] = array( - 'value' => FIMA_SORT_DATE, - 'type' => 'enum', - 'enum' => array( - FIMA_SORT_DATE => _("Date"), - FIMA_SORT_ASSET => _("Asset Account"), - FIMA_SORT_ACCOUNT => _("Posting Account"), - FIMA_SORT_AMOUNT => _("Amount"), - FIMA_SORT_DESC => _("Description") - ), - 'desc' => _("Sort postings by:") -); - -// alternate sort column -$_prefs['altsortby'] = array( - 'value' => FIMA_SORT_ACCOUNT, - 'type' => 'enum', - 'enum' => array( - FIMA_SORT_DATE => _("Date"), - FIMA_SORT_ASSET => _("Asset Account"), - FIMA_SORT_ACCOUNT => _("Posting Account"), - FIMA_SORT_AMOUNT => _("Amount"), - FIMA_SORT_DESC => _("Description") - ), - 'desc' => _("Then:") -); - -// user preferred sorting direction -$_prefs['sortdir'] = array( - 'value' => FIMA_SORT_ASCEND, - 'type' => 'enum', - 'enum' => array( - FIMA_SORT_ASCEND => _("Ascending"), - FIMA_SORT_DESCEND => _("Descending") - ), - 'desc' => _("Sort direction:") -); - -// format for wildcards -$_prefs['wildcard_format'] = array( - 'value' => 'dos', - 'type' => 'enum', - 'enum' => array( - 'dos' => _("DOS (* and ?)"), - 'sql' => _("SQL (% and _)"), - 'none' => _("none") - ), - 'desc' => _("Select the format for wildcards for text search:") -); - -// format for amounts -$_prefs['amount_format'] = array( - 'value' => '.,', - 'type' => 'enum', - 'enum' => array( - '.,' => _("-12.345.678,90"), - ',.' => _("-12,345,678.90"), - ' ,' => _("-12 345 678,90"), - '\'.' => _("-12'345'678.90") - ), - 'desc' => _("Select the format for amounts:") -); - -// sign for expenses -$_prefs['expenses_sign'] = array( - 'value' => 0, - 'type' => 'checkbox', - 'desc' => _("Enter expenses with negative sign?") -); - -// preference for delete confirmation dialog. -$_prefs['delete_opt'] = array( - 'value' => 1, - 'type' => 'checkbox', - 'desc' => _("Do you want to confirm deleting postings?") -); - -// report graph size -$_prefs['report_graphsize'] = array( - 'value' => '800x600', - 'type' => 'enum', - 'enum' => array( - '400x300' => _("400 x 300 Pixel"), - '800x600' => _("800 x 600 Pixel"), - '1024x768' => _("1024 x 768 Pixel"), - '1600x1200' => _("1600 x 1200 Pixel") - ), - 'desc' => _("Select the canvas size for chart reports:") -); diff --git a/fima/config/report.php.dist b/fima/config/report.php.dist deleted file mode 100644 index 6d64a26e3..000000000 --- a/fima/config/report.php.dist +++ /dev/null @@ -1,13 +0,0 @@ - _("General Overview"), - 'PeriodOverview' => _("Period Overview"), - 'AccountOverview' => _("Account Overview"), - 'AssetOverview' => _("Asset Overview"), - 'Analysis' => _("Analysis"), - 'Trend' => _("Trend"), - ); diff --git a/fima/data.php b/fima/data.php deleted file mode 100644 index 771332b37..000000000 --- a/fima/data.php +++ /dev/null @@ -1,227 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (ASL). If you - * did not receive this file, see http://www.horde.org/licenses/asl.php. - */ - -function _cleanupData() -{ - $GLOBALS['import_step'] = 1; - return Horde_Data::IMPORT_FILE; -} - -@define('FIMA_BASE', dirname(__FILE__)); -require_once FIMA_BASE . '/lib/base.php'; - -$ledger = Fima::getActiveLedger(); - -/* Importable file types. */ -$file_types = array('csv' => _("CSV"), - 'tsv' => _("TSV")); - -/* Templates for the different import steps. */ -$templates = array( - Horde_Data::IMPORT_CSV => array($registry->get('templates', 'horde') . '/data/csvinfo.inc'), - Horde_Data::IMPORT_TSV => array($registry->get('templates', 'horde') . '/data/tsvinfo.inc'), - Horde_Data::IMPORT_MAPPED => array($registry->get('templates', 'horde') . '/data/csvmap.inc'), - Horde_Data::IMPORT_DATETIME => array($registry->get('templates', 'horde') . '/data/datemap.inc'), - Horde_Data::IMPORT_FILE => array(FIMA_TEMPLATES . '/data/import.inc', FIMA_TEMPLATES . '/data/export.inc'), -); - -/* Field/clear name mapping. */ -$app_fields = array('date' => _("Date"), - 'asset' => _("Asset Account"), - 'account' => _("Account"), - 'desc' => _("Description"), - 'amount' => _("Amount"), - 'eo' => _("e.o.")); - -/* Date/time fields. */ -$time_fields = array('date' => 'date'); - -/* Initial values. */ -$param = array('time_fields' => $time_fields, - 'file_types' => $file_types); -$import_format = Horde_Util::getFormData('import_format', ''); -$import_step = Horde_Util::getFormData('import_step', 0) + 1; -$next_step = Horde_Data::IMPORT_FILE; -$actionID = Horde_Util::getFormData('actionID'); -$error = false; - -/* Loop through the action handlers. */ -switch ($actionID) { -case 'export': - $data = array(); - - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - if (is_a($storage, 'PEAR_Error')) { - $notification->push(sprintf(_("Failed to access the ledger: %s"), $storage->getMessage()), 'horde.error'); - $error = true; - break; - } - $params = $storage->getParams(); - - $filters = array(array('type', $prefs->getValue('active_postingtype'))); - - /* Get accounts and postings. */ - $accounts = Fima::listAccounts(); - $postings = Fima::listPostings($filters); - - foreach ($postings as $postingId => $posting) { - $row = array(); - foreach ($posting as $key => $value) { - switch ($key) { - case 'date': - $row[$key] = strftime(Fima::convertDateFormat($prefs->getValue('date_format')), $value); - break; - case 'asset': - case 'account': - $row[$key] = isset($accounts[$value]) ? $accounts[$value]['number'] : ''; - break; - case 'amount': - $row[$key] = Fima::convertValueToAmount($value); - break; - case 'eo': - case 'desc': - $row[$key] = Horde_String::convertCharset($value, $GLOBALS['registry']->getCharset(), $params['charset']); - break; - default: - break; - } - } - $data[] = $row; - } - - if (!count($data)) { - $notification->push(_("There were no postings to export."), 'horde.message'); - $error = true; - break; - } - - switch (Horde_Util::getFormData('exportID')) { - case EXPORT_CSV: - $injector->getInstance('Horde_Data')->getData('Csv', array('cleanup' => '_cleanupData'))->exportFile(_("postings.csv"), $data, true); - exit; - - case EXPORT_TSV: - $injector->getInstance('Horde_Data')->getData('Tsv', array('cleanup' => '_cleanupData'))->exportFile(_("postings.tsv"), $data, true); - exit; - } - break; - -case Horde_Data::IMPORT_FILE: - $storage = &Fima_Driver::singleton($ledger); - if (is_a($storage, 'PEAR_Error')) { - $notification->push(sprintf(_("Failed to access the ledger: %s"), $storage->getMessage()), 'horde.error'); - $error = true; - break; - } - - $_SESSION['import_data']['target'] = $ledger; - $_SESSION['import_data']['purge'] = Horde_Util::getFormData('purge'); - break; -} - -if (!$error) { - try { - $data = $injector->getInstance('Horde_Data')->getData($import_format, array('cleanup' => '_cleanupData')); - $next_step = $data->nextStep($actionID, $param); - } catch (Horde_Data_Exception $e) { - if ($data) { - $notification->push($e, 'horde.error'); - $next_step = $data->cleanup(); - } else { - $notification->push(_("This file format is not supported."), 'horde.error'); - $next_step = Horde_Data::IMPORT_FILE; - } - } -} - -/* We have a final result set. */ -if (is_array($next_step)) { - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - if (is_a($storage, 'PEAR_Error')) { - $notification->push(sprintf(_("Failed to access the ledger: %s"), $storage->getMessage()), 'horde.error'); - } - - $params = $storage->getParams(); - - /* Purge old postings if requested. */ - if ($_SESSION['import_data']['purge']) { - $result = $storage->deleteAll(false, $prefs->getValue('active_postingtype')); - if (is_a($result, 'PEAR_Error')) { - $notification->push(sprintf(_("The postings could not be purged: %s"), $result->getMessage()), 'horde.error'); - } else { - $notification->push(_("Postings successfully purged."), 'horde.success'); - } - } - - /* Get accounts and postings. */ - $accounts = Fima::listAccounts(); - $accounts_indices = array(); - foreach ($accounts as $account) { - $accounts_indices[$account['number']] = $account['account_id']; - } - - foreach ($next_step as $row) { - $row['type'] = $prefs->getValue('active_postingtype'); - $row['asset'] = sprintf('%\'04d', $row['asset']); - $row['asset'] = isset($accounts_indices[$row['asset']]) ? $accounts_indices[$row['asset']] : null; - $row['account'] = sprintf('%\'04d', $row['account']); - $row['account'] = isset($accounts_indices[$row['account']]) ? $accounts_indices[$row['account']] : null; - $row['date'] = Fima::convertDateToStamp($row['date'], Fima::convertDateFormat($prefs->getValue('date_format'))); - $row['amount'] = Fima::convertAmountToValue($row['amount']); - if ($prefs->getValue('expenses_sign') == 0) { - if ($row['account'] !== null) { - if ($accounts[$row['account']]['type'] == FIMA_ACCOUNTTYPE_EXPENSE) { - $row['amount'] *= -1; - } - } else { - $row['amount'] *= -1; - } - } - $row['desc'] = isset($row['desc']) ? trim($row['desc']) : ''; - $row['eo'] = isset($row['eo']) ? (bool)trim($row['eo']) : false; - $result = $storage->addPosting($row['type'], $row['date'], $row['asset'], $row['account'], $row['eo'], $row['amount'], $row['desc']); - if (is_a($result, 'PEAR_Error')) { - break; - } - } - - if (!count($next_step)) { - $notification->push(sprintf(_("The %s file didn't contain any postings."), - $file_types[$_SESSION['import_data']['format']]), 'horde.error'); - } else { - $notification->push(sprintf(_("%s successfully imported"), - $file_types[$_SESSION['import_data']['format']]), 'horde.success'); - } - $next_step = $data->cleanup(); -} - -$title = _("Import/Export Postings"); -require FIMA_TEMPLATES . '/common-header.inc'; -require FIMA_TEMPLATES . '/menu.inc'; - -if ($next_step == Horde_Data::IMPORT_FILE) { - /* Build the charset options. */ - $charsets = $registry->nlsconfig['encodings']; - asort($charsets); - $all_charsets = $registry->nlsconfig['charsets']; - natcasesort($all_charsets); - foreach ($all_charsets as $charset) { - if (!isset($charsets[$charset])) { - $charsets[$charset] = $charset; - } - } - $my_charset = $GLOBALS['registry']->getCharset(true); -} - -foreach ($templates[$next_step] as $template) { - require $template; - echo '
'; -} -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/fima/docs/CHANGES b/fima/docs/CHANGES deleted file mode 100644 index 653ced5c6..000000000 --- a/fima/docs/CHANGES +++ /dev/null @@ -1,12 +0,0 @@ ---- -v1.1 ---- - -[trt] Close accounts. -[trt] Hide null rows in reports. - ---- -v1.0 ---- - -[trt] Initial Release. diff --git a/fima/docs/CREDITS b/fima/docs/CREDITS deleted file mode 100644 index 65c8ce6ff..000000000 --- a/fima/docs/CREDITS +++ /dev/null @@ -1,26 +0,0 @@ -=========================== - Fima Development Team -=========================== - - -Core Developers -=============== - -- Thomas Trethan - - -Localization -============ - -===================== ====================================================== -German Thomas Trethan - Gerhard Trethan -===================== ====================================================== - - -Contributions -============= - -- Gerhard Trethan, who inspired and supported the work on fima and had - programmed the basis of fima a while ago, a double entry based ledger in - visual basic. diff --git a/fima/docs/INSTALL b/fima/docs/INSTALL deleted file mode 100644 index c21010c9c..000000000 --- a/fima/docs/INSTALL +++ /dev/null @@ -1,225 +0,0 @@ -========================= - Installing Fima 1.0 -========================= - -.. contents:: Contents -.. section-numbering:: - -This document contains instructions for installing Fima. - -For information on the capabilities and features of Skeleton, see the file -README_ in the top-level directory of the Skeleton distribution. - - -Obtaining Fima -================== - -Fima can be obtained from the Horde website and FTP server, at - - http://www.horde.org/fima/ - - ftp://ftp.horde.org/pub/fima/ - -Or use the mirror closest to you: - - http://www.horde.org/mirrors.php - -Bleeding-edge development versions of Fima are available via CVS; see the -file `horde/docs/HACKING`_ in the Horde distribution, or the website -http://www.horde.org/source/, for information on accessing the Horde CVS -repository. - - -Prerequisites -============= - -To function properly, Fima **requires** the following: - -1. A working Horde installation. - - Fima runs within the `Horde Application Framework`_, a set of common - tools for Web applications written in PHP. You must install Horde before - installing Fima. - - .. Important:: Fima 1.0 requires version 3.0+ of the Horde Framework - - earlier versions of Horde will **not** work. - - .. _`Horde Application Framework`: http://www.horde.org/horde/ - - The Horde Framework can be obtained from the Horde website and FTP server, - at - - http://www.horde.org/horde/ - - ftp://ftp.horde.org/pub/horde/ - - Many of Fima's prerequisites are also Horde prerequisites. - - .. Important:: Be sure to have completed all of the steps in the - `horde/docs/INSTALL`_ file for the Horde Framework before - installing Fima. - -2. The following PEAR packages: - (See `horde/docs/INSTALL`_ for instructions on installing PEAR packages) - - a. Image_Graph 0.7.2 [OPTIONAL] - - Fima uses the Image_Graph package for creating graphical reports. - -3. SQL support. - - Fima will store its data in an SQL database. Build PHP with whichever - SQL driver you require; see the Horde INSTALL_ file for details. - - -Installing Fima -=================== - -Fima is written in PHP, and must be installed in a web-accessible -directory. The precise location of this directory will differ from system to -system. Conventionally, Fima is installed directly underneath Horde in the -web server's document tree. - -Since Fima is written in PHP, there is no compilation necessary; simply -expand the distribution where you want it to reside and rename the root -directory of the distribution to whatever you wish to appear in the URL. For -example, with the Apache web server's default document root of -``/usr/local/apache/htdocs``, you would type:: - - cd /usr/local/apache/htdocs/horde - tar zxvf /path/to/fima-h3-x.y.z.tar.gz - mv fima-h3-x.y.z fima - -and would then find Fima at the URL:: - - http://your-server/horde/fima/ - - -Configuring Fima -==================== - -1. Configuring Horde for Fima - - a. Register the application - - In ``horde/config/registry.php``, find the ``applications['fima']`` - stanza. The default settings here should be okay, but you can change - them if desired. If you have changed the location of Fima relative - to Horde, either in the URL, in the filesystem or both, you must update - the ``fileroot`` and ``webroot`` settings to their correct values. - -2. Creating the database tables - - The specific steps to create Fima's database tables depend on which - database you've chosen to use. - - First, look in ``scripts/sql/`` to see if a script already exists for your - database type. If so, you should be able to simply execute that script as - superuser in your database. (Note that executing the script as the "horde" - user will probably fail when granting privileges.) - - If such a script does not exist, you'll need to build your own, using the - file ``fima.sql`` as a starting point. If you need assistance in - creating database tables, you may wish to let us know on the Fima - mailing list. - - You will also need to make sure that the "horde" user in your database has - table-creation privileges, so that the tables that `PEAR DB`_ uses to - provide portable sequences can be created. - - .. _`PEAR DB`: http://pear.php.net/DB - -3. Configuring Fima - - To configure Fima, change to the ``config/`` directory of the installed - distribution, and make copies of all of the configuration ``dist`` files - without the ``dist`` suffix:: - - cd config/ - for foo in *.dist; do cp $foo `basename $foo .dist`; done - - Or on Windows:: - - copy *.dist *. - - Documentation on the format and purpose of those files can be found in each - file. You may edit these files if you wish to customize Fima's - appearance and behavior. With one exception (``foo.php``) the defaults will - be correct for most sites. - - You must login to Horde as a Horde Administrator to finish the - configuration of Fima. Use the Horde ``Administration`` menu item to - get to the administration page, and then click on the ``Configuration`` - icon to get the configuration page. Select ``Fima Name`` from the - selection list of applications. Fill in or change any configuration values - as needed. When done click on ``Generate Fima Name Configuration`` to - generate the ``conf.php`` file. If your web server doesn't have write - permissions to the Fima configuration directory or file, it will not be - able to write the file. In this case, go back to ``Configuration`` and - choose one of the other methods to create the configuration file - ``fima/config/conf.php``. - - Note for international users: Fima uses GNU gettext to provide local - translations of text displayed by applications; the translations are found - in the ``po/`` directory. If a translation is not yet available for your - locale (and you wish to create one), see the ``horde/po/README`` file, or - if you're having trouble using a provided translation, please see the - `horde/docs/TRANSLATIONS`_ file for instructions. - -4. More instructions, upgrading, securing, etc. - -5. Testing Fima - - Once you have configured Fima, bring up the included test page in your - Web browser to ensure that all necessary prerequisites have been met. See - the `horde/docs/INSTALL`_ document for further details on the Horde test - script. - - Test at least the following: - - - Creating a new account - - Modifying an account - - Deleting an account - - Creating a new posting - - Modifying a posting - - Delete a posting - - -Known Problems -============== - -None yet. - - -Obtaining Support -================= - -If you encounter problems with Fima, help is available! - -The Horde Frequently Asked Questions List (FAQ), available on the Web at - - http://www.horde.org/faq/ - -The Horde Project runs a number of mailing lists, for individual applications -and for issues relating to the project as a whole. Information, archives, and -subscription information can be found at - - http://www.horde.org/mail/ - -Lastly, Horde developers, contributors and users may also be found on IRC, -on the channel #horde on the Freenode Network (irc.freenode.net). - -Please keep in mind that Fima is free software written by volunteers. -For information on reasonable support expectations, please read - - http://www.horde.org/support.php - -Thanks for using Fima! - -The Fima team - - -.. _README: ?f=README.html -.. _`horde/docs/HACKING`: ../../horde/docs/?f=HACKING.html -.. _`horde/docs/INSTALL`: ../../horde/docs/?f=INSTALL.html -.. _`horde/docs/TRANSLATIONS`: ../../horde/docs/?f=TRANSLATIONS.html diff --git a/fima/docs/RELEASE_NOTES b/fima/docs/RELEASE_NOTES deleted file mode 100644 index d28010628..000000000 --- a/fima/docs/RELEASE_NOTES +++ /dev/null @@ -1,37 +0,0 @@ -notes['fm']['focus'] = 0; - -/* Mailing list release notes. */ -$this->notes['ml']['changes'] = <<notes['fm']['changes'] = <<notes['name'] = 'Fima'; -$this->notes['fm']['project'] = 'fima'; -$this->notes['fm']['branch'] = 'Default'; diff --git a/fima/docs/TODO b/fima/docs/TODO deleted file mode 100644 index 7b2dc61fe..000000000 --- a/fima/docs/TODO +++ /dev/null @@ -1,9 +0,0 @@ -================================ - Fima Development TODO List -================================ - -- fix search with umlaute -- drill down in reports -- shift all postings from an account or only selected -- simplified entering of budget/forecast values analog to report Account Overview -- after selecting asset account immediately show result diff --git a/fima/index.php b/fima/index.php deleted file mode 100644 index 6fc8aec12..000000000 --- a/fima/index.php +++ /dev/null @@ -1,11 +0,0 @@ - - * - * See the enclosed file COPYING for license information (GPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. - * - * @author Thomas Trethan - */ - -require dirname(__FILE__) . '/postings.php'; diff --git a/fima/ledgers/create.php b/fima/ledgers/create.php deleted file mode 100644 index 1b6c9fb30..000000000 --- a/fima/ledgers/create.php +++ /dev/null @@ -1,38 +0,0 @@ -getAuth() || $prefs->isLocked('active_ledger')) { - Horde::url('postings.php', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$form = new Fima_CreateLedgerForm($vars); - -// Execute if the form is valid. -if ($form->validate($vars)) { - $result = $form->execute(); - if (is_a($result, 'PEAR_Error')) { - $notification->push($result, 'horde.error'); - } else { - $notification->push(sprintf(_("The ledger \"%s\" has been created."), $vars->get('name')), 'horde.success'); - } - - Horde::url('ledgers/', true)->redirect(); -} - -$title = $form->getTitle(); -require FIMA_TEMPLATES . '/common-header.inc'; -require FIMA_TEMPLATES . '/menu.inc'; -echo $form->renderActive($form->getRenderer(), $vars, 'create.php', 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/fima/ledgers/delete.php b/fima/ledgers/delete.php deleted file mode 100644 index 0309a7fe0..000000000 --- a/fima/ledgers/delete.php +++ /dev/null @@ -1,53 +0,0 @@ -getAuth()) { - Horde::url('postings.php', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$ledger_id = $vars->get('l'); -if ($ledger_id == $GLOBALS['registry']->getAuth()) { - $notification->push(_("This ledger cannot be deleted."), 'horde.warning'); - Horde::url('ledgers/', true)->redirect(); -} - -$ledger = $fima_shares->getShare($ledger_id); -if (is_a($ledger, 'PEAR_Error')) { - $notification->push($ledger, 'horde.error'); - Horde::url('ledgers/', true)->redirect(); -} -if ($ledger->get('owner') != $GLOBALS['registry']->getAuth()) { - $notification->push(_("You are not allowed to delete this ledger."), 'horde.error'); - Horde::url('ledgers/', true)->redirect(); -} - -$form = new Fima_DeleteLedgerForm($vars, $ledger); - -// Execute if the form is valid (must pass with POST variables only). -if ($form->validate(new Horde_Variables($_POST))) { - $result = $form->execute(); - if (is_a($result, 'PEAR_Error')) { - $notification->push($result, 'horde.error'); - } elseif ($result) { - $notification->push(sprintf(_("The ledger \"%s\" has been deleted."), $ledger->get('name')), 'horde.success'); - } - - Horde::url('ledgers/', true)->redirect(); -} - -$title = $form->getTitle(); -require FIMA_TEMPLATES . '/common-header.inc'; -require FIMA_TEMPLATES . '/menu.inc'; -echo $form->renderActive($form->getRenderer(), $vars, 'delete.php', 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/fima/ledgers/edit.php b/fima/ledgers/edit.php deleted file mode 100644 index 12bc94c49..000000000 --- a/fima/ledgers/edit.php +++ /dev/null @@ -1,53 +0,0 @@ -getAuth()) { - Horde::url('postings.php', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$ledger = $fima_shares->getShare($vars->get('l')); -if (is_a($ledger, 'PEAR_Error')) { - $notification->push($ledger, 'horde.error'); - Horde::url('ledgers/', true)->redirect(); -} -if ($ledger->get('owner') != $GLOBALS['registry']->getAuth()) { - $notification->push(_("You are not allowed to change this ledger."), 'horde.error'); - Horde::url('ledgers/', true)->redirect(); -} -$form = new Fima_EditLedgerForm($vars, $ledger); - -// Execute if the form is valid. -if ($form->validate($vars)) { - $original_name = $ledger->get('name'); - $result = $form->execute(); - if (is_a($result, 'PEAR_Error')) { - $notification->push($result, 'horde.error'); - } else { - if ($ledger->get('name') != $original_name) { - $notification->push(sprintf(_("The ledger \"%s\" has been renamed to \"%s\"."), $original_name, $ledger->get('name')), 'horde.success'); - } else { - $notification->push(sprintf(_("The ledger \"%s\" has been saved."), $original_name), 'horde.success'); - } - } - - Horde::url('ledgers/', true)->redirect(); -} - -$vars->set('name', $ledger->get('name')); -$vars->set('description', $ledger->get('desc')); -$title = $form->getTitle(); -require FIMA_TEMPLATES . '/common-header.inc'; -require FIMA_TEMPLATES . '/menu.inc'; -echo $form->renderActive($form->getRenderer(), $vars, 'edit.php', 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/fima/ledgers/index.php b/fima/ledgers/index.php deleted file mode 100644 index c52ba17c1..000000000 --- a/fima/ledgers/index.php +++ /dev/null @@ -1,41 +0,0 @@ -getAuth()) { - require FIMA_BASE . '/postings.php'; - exit; -} - -$edit_url_base = Horde::url('ledgers/edit.php'); -$perms_url_base = Horde::url($registry->get('webroot', 'horde') . '/services/shares/edit.php?app=fima', true); -$delete_url_base = Horde::url('ledgers/delete.php'); - -// Get the shares owned by the current user, and figure out what we will -// display the share name as to the user. -$ledgers = Fima::listLedgers(true); -$sorted_ledgers = array(); -foreach ($ledgers as $ledger) { - $sorted_ledgers[$ledger->getName()] = $ledger->get('name'); -} -asort($sorted_ledgers); - -$browse_img = Horde::img('accounts.png', _("Ledger")); -$edit_img = Horde::img('edit.png', _("Edit")); -$perms_img = Horde::img('perms.png', _("Change Permissions")); -$delete_img = Horde::img('delete.png', _("Delete")); - -Horde::addScriptFile('tables.js', 'horde'); -$title = _("Manage Ledgers"); -require FIMA_TEMPLATES . '/common-header.inc'; -require FIMA_TEMPLATES . '/menu.inc'; -require FIMA_TEMPLATES . '/ledgers_list.php'; -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/fima/lib/Application.php b/fima/lib/Application.php deleted file mode 100644 index 8182bc5ff..000000000 --- a/fima/lib/Application.php +++ /dev/null @@ -1,74 +0,0 @@ -group) { - case 'share': - if (!$GLOBALS['prefs']->isLocked('active_ledger')) { - $ui->override['active_ledger'] = Fima::listLedgers(); - } - break; - } - } - - /** - * Generate code used to display a special preference. - * - * @param Horde_Core_Prefs_Ui $ui The UI object. - * @param string $item The preference name. - * - * @return string The HTML code to display on the prefs page. - */ - public function prefsSpecial($ui, $item) - { - switch ($item) { - case 'closedperiodselect': - return _("Closed by period:") . - '
' . - Fima::buildDateWidget('closedperiod', (int)$GLOBALS['prefs']->getValue('closed_period'), '', _("None"), true) . - '

'; - } - - return ''; - } - - /** - * Special preferences handling on update. - * - * @param Horde_Core_Prefs_Ui $ui The UI object. - * @param string $item The preference name. - * - * @return boolean True if preference was updated. - */ - public function prefsSpecialUpdate($ui, $item) - { - switch ($item) { - case 'closedperiodselect': - $period = $ui->vars->closedperiod; - $period = ((int)$period['year'] > 0 && (int)$period['month'] > 0) - ? mktime(0, 0, 0, $period['month'] + 1, 0, $period['year']) - : 0; - $GLOBALS['prefs']->setValue('closed_period', $period); - return true; - } - } - -} diff --git a/fima/lib/Block/summary.php b/fima/lib/Block/summary.php deleted file mode 100644 index 21a496d31..000000000 --- a/fima/lib/Block/summary.php +++ /dev/null @@ -1,159 +0,0 @@ -_params['block_title']) - ? $this->_params['block_title'] - : $registry->get('name'); - return Horde::link(Horde::url($registry->getInitialPage(), true)) - . htmlspecialchars($label) . ''; - } - - function _params() - { - require_once dirname(__FILE__) . '/../base.php'; - $ledgers = array(); - foreach (Fima::listLedgers() as $id => $ledger) { - $ledgers[$id] = $ledger->get('name'); - } - - return array('block_title' => array( - 'type' => 'text', - 'name' => _("Block title"), - 'default' => $GLOBALS['registry']->get('name')), - 'show_ledger' => array( - 'type' => 'enum', - 'name' => _("Show summary of this ledger"), - 'default' => $GLOBALS['registry']->getAuth(), - 'values' => $ledgers), - 'show_months' => array( - 'type' => 'enum', - 'name' => _("Number of months to display"), - 'default' => '3', - 'values' => array( - '1' => '1', - '2' => '2', - '3' => '3', - '4' => '4', - '5' => '5', - '6' => '6', - ))); - } - - function _content() - { - global $registry, $prefs; - require_once dirname(__FILE__) . '/../base.php'; - - $now = time(); - $html = ''; - - /* Get account types and posting types. */ - $accounttypes = Fima::getAccountTypes(); - - /* Params. */ - $showmonths = $this->_params['show_months']; - $datefmt = Fima::convertDateToPeriodFormat($GLOBALS['prefs']->getValue('date_format')); - $period_start = mktime(0, 0, 0, date('n') - $showmonths + 1, 1); - $period_end = mktime(0, 0, 0); - - /* Rows. */ - $rows = array(FIMA_ACCOUNTTYPE_INCOME => $accounttypes[FIMA_ACCOUNTTYPE_INCOME], - FIMA_ACCOUNTTYPE_EXPENSE => $accounttypes[FIMA_ACCOUNTTYPE_EXPENSE], - '__result__' => _("Total Result"), - '__resultasset__' => _("Asset Result")); - - /* Columns. */ - $cols = array(); - $coldummy = array(); - - for ($period = $period_start; $period <= $period_end; $period = strtotime('+1 month', $period)) { - $colId = strftime('%Y%m', $period); - $cols[$colId] = strftime($datefmt, $period); - $coldummy[$colId] = 0; - } - - /* Initialize matrix. */ - $data = array('__header__' => array('__header__' => '')); - foreach ($cols as $colId => $col) { - $data['__header__'][$colId] = $col; - } - foreach ($rows as $rowId => $row) { - $data[$rowId] = array('__header__' => $row) + $coldummy; - } - - /* Results. */ - $filters = array(); - $filters[] = array('account_type', FIMA_ACCOUNTTYPE_ASSET, '<>'); - $filters[] = array('type', FIMA_POSTINGTYPE_ACTUAL); - $filters[] = array('date', (int)$period_start, '>='); - $filters[] = array('date', (int)$period_end, '<='); - $result = Fima::getResults(array('date_month', 'account_type'), $filters); - if (is_a($result, 'PEAR_Error')) { - return '' . _("Error when retrieving results.") . ''; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $data[$rowId][$colId] = $value; - $data['__result__'][$colId] += $value; - } - } - - /* Asset Results. */ - $filters = array(); - $filters[] = array('account_type', FIMA_ACCOUNTTYPE_ASSET, '<>'); - $filters[] = array('type', FIMA_POSTINGTYPE_ACTUAL); - $filters[] = array('date', (int)$period_start, '<'); - $result = Fima::getResults(array('type'), $filters); - if (is_a($result, 'PEAR_Error')) { - return '' . _("Error when retrieving results.") . ''; - } - $assetresult = 0; - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $assetresult += $value; - } - } - foreach ($data['__resultasset__'] as $colId => $col) { - if (preg_match('/__header.*__/', $colId)) { - continue; - } - $assetresult += $data['__result__'][$colId]; - $data['__resultasset__'][$colId] = $assetresult; - } - - /* Output. */ - foreach ($data as $rowId => $row) { - $html .= ''; - foreach ($row as $colId => $value) { - if ($rowId === '__header__') { - $html .= '' . htmlspecialchars($value) . ''; - } elseif ($colId === '__header__') { - $html .= '' . htmlspecialchars($value) . ''; - } else { - $html .= '' . Fima::convertValueToAmount($value) . ''; - } - } - $html .= ''; - } - - if (empty($html)) { - return '' . _("No results to display") . ''; - } - - return '' - . $html . '
'; - } - -} diff --git a/fima/lib/Block/tree_menu.php b/fima/lib/Block/tree_menu.php deleted file mode 100644 index f6dd0e5d3..000000000 --- a/fima/lib/Block/tree_menu.php +++ /dev/null @@ -1,34 +0,0 @@ -addNode( - $parent . $menu[0], - $parent, - $menu[1], - $indent + 1, - false, - array( - 'icon' => Horde_Themes::img($menu[2]), - 'url' => $menu[3] - ) - ); - } - } - -} diff --git a/fima/lib/Driver.php b/fima/lib/Driver.php deleted file mode 100644 index 766607343..000000000 --- a/fima/lib/Driver.php +++ /dev/null @@ -1,411 +0,0 @@ - - * @package Fima - */ -class Fima_Driver { - - /** - * Array holding the current accounts. Each array entry is a hash - * describing an account. The array is indexed by accountId. - * - * @var array - */ - var $_accounts = array(); - - /** - * Array holding the current postings. Each array entry is a hash - * describing a posting. The array is indexed by postingId. - * - * @var array - */ - var $_postings = array(); - - /** - * Integer containing the current total count of postings. - * - * @var integer - */ - var $_postingsCount = 0; - - /** - * Amount containing the current total result of postings. - * - * @var float - */ - var $_postingsResult = 0; - - /** - * String containing the current ledger. - * - * @var string - */ - var $_ledger = ''; - - /** - * Hash containing connection parameters. - * - * @var array - */ - var $_params = array(); - - /** - * Constructor - just store the $params in our newly-created - * object. All other work is done by initialize(). - * - * @param array $params Any parameters needed for this driver. - */ - function Fima_Driver($params = array(), $errormsg = null) - { - $this->_params = $params; - if (is_null($errormsg)) { - $this->_errormsg = _("The Finances backend is not currently available."); - } else { - $this->_errormsg = $errormsg; - } - } - - /** - * Returns the current driver's additional parameters. - * - * @return array Hash containing the driver's additional parameters. - */ - function getParams() - { - return $this->_params; - } - - /** - * Lists accounts based on the given criteria. All accounts will be - * returned by default. - * - * @return array Returns a list of the requested accounts. - */ - function listAccounts() - { - return $this->_accounts; - } - - /** - * Lists postings based on the given criteria. All postings will be - * returned by default. - * - * @return array Returns a list of the requested postings. - */ - function listPostings() - { - return $this->_postings; - } - - /** - * Adds an account. - * - * @param string $number The number of the account. - * @param string $type The type of the account. - * @param string $name The name (short) of the account. - * @param boolean $eo Extraordinary account. - * @param string $desc The description (long) of the account. - * @param boolean $closed Close account. - * - * @return mixed ID of the new account or PEAR_Error - */ - function addAccount($number, $type, $name, $eo, $desc, $closed) - { - $accountId = $this->_addAccount($number, $type, $name, $eo, $desc, $closed); - if (is_a($accountId, 'PEAR_Error')) { - return $accountId; - } - - /* Log the creation of this item in the history log. */ - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':' . $accountId, array('action' => 'add'), true); - - return $accountId; - } - - /** - * Modifies an existing account. - * - * @param string $accountId The account to modify. - * @param string $number The number of the account. - * @param string $type The type of the account. - * @param string $name The name (short) of the task. - * @param boolean $eo Extraordinary account. - * @param string $desc The description (long) of the task. - * @param boolean $closed Close account. - * - * return mixed True or PEAR_Error - */ - function modifyAccount($accountId, $number, $type, $name, $eo, $desc, $closed) - { - $modify = $this->_modifyAccount($accountId, $number, $type, $name, $eo, $desc, $closed); - if (is_a($modify, 'PEAR_Error')) { - return $modify; - } - - /* Log the modification of this item in the history log. */ - $account = $this->getAccount($accountId); - if (!is_a($account, 'PEAR_Error')) { - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':' . $account['account_id'], array('action' => 'modify'), true); - } - - return true; - } - - /** - * Deletes an account and deletes/shifts of subaccounts and postings. - * - * @param string $accountId The account to delete. - * @param mixed $dsSubaccounts True/false when deleting subaccounts, - * accountId when shifting subaccounts - * @param mixed $dsPostings True/false when deleting postings, - * accountId when shifting postings - * - * @return mixed True or PEAR_Error - */ - function deleteAccount($accountId, $dsSubaccounts = false, $dsPostings = true) - { - /* Get the account's details for use later. */ - $account = $this->getAccount($accountId); - - $delete = $this->_deleteAccount($accountId, $dsSubaccounts, $dsPostings); - if (is_a($delete, 'PEAR_Error')) { - return $delete; - } - - /* Log the deletion of this item in the history log. */ - if (!is_a($account, 'PEAR_Error')) { - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':' . $account['account_id'], array('action' => 'delete'), true); - } - - return true; - } - - /** - * Adds a posting. - * - * @param string $type The posting type. - * @param integer $date The posting date. - * @param string $asset The ID of the asset account. - * @param string $account The ID of the account. - * @param boolean $eo Extraordinary posting. - * @param float $amount The posting amount. - * @param string $desc The posting description. - * - * @return mixed ID of the new posting or PEAR_Error - */ - function addPosting($type, $date, $asset, $account, $eo, $amount, $desc) - { - $postingId = $this->_addPosting($type, $date, $asset, $account, $eo, $amount, $desc); - if (is_a($postingId, 'PEAR_Error')) { - return $postingId; - } - - /* Log the creation of this item in the history log. */ - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':' . $postingId, array('action' => 'add'), true); - - return $postingId; - } - - /** - * Modifies an existing posting. - * - * @param string $postingId The posting to modify. - * @param string $type The posting type. - * @param integer $date The posting date. - * @param string $asset The ID of the asset account. - * @param string $account The ID of the account. - * @param boolean $eo Extraordinary posting. - * @param float $amount The posting amount. - * @param string $desc The posting description. - * - * @return mixed True or PEAR_Error - */ - function modifyPosting($postingId, $type, $date, $asset, $account, $eo, $amount, $desc) - { - $modify = $this->_modifyPosting($postingId, $type, $date, $asset, $account, $eo, $amount, $desc); - if (is_a($modify, 'PEAR_Error')) { - return $modify; - } - - /* Log the modification of this item in the history log. */ - $posting = $this->getPosting($postingId); - if (!is_a($posting, 'PEAR_Error')) { - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':' . $posting['posting_id'], array('action' => 'modify'), true); - } - - return true; - } - - /** - * Deletes a posting. - * - * @param string $postingId The posting to delete. - * - * @return mixed True or PEAR_Error - */ - function deletePosting($postingId) - { - /* Get the posting's details for use later. */ - $posting = $this->getPosting($postingId); - - $delete = $this->_deletePosting($postingId); - if (is_a($delete, 'PEAR_Error')) { - return $delete; - } - - /* Log the deletion of this item in the history log. */ - if (!is_a($posting, 'PEAR_Error')) { - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':' . $posting['posting_id'], array('action' => 'delete'), true); - } - - return true; - } - - /** - * Shifts a posting. - * - * @param string $postingId The posting to shift. - * @param string $type The posting type shifting to. - * @param string $asset The ID of the asset account. - * @param string $account The ID of the account. - * - * @return mixed True or PEAR_Error - */ - function shiftPosting($postingId, $type, $asset, $account) - { - /* Get the posting's details for use later. */ - $posting = $this->getPosting($postingId); - $shift = $this->_shiftPosting($postingId, $type, $asset, $account); - if (is_a($shift, 'PEAR_Error')) { - return $shift; - } - - /* Log the shifting of this item in the history log. */ - if (!is_a($posting, 'PEAR_Error')) { - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':' . $posting['posting_id'], array('action' => 'shift'), true); - } - - return true; - } - - /** - * Deletes all postings and accounts. - * - * @param mixed $accounts boolean or account_type - * @param mixed $accounts boolean or posting_type. - * - * @return mixed True or PEAR_Error - */ - function deleteAll($accounts = true, $postings = true) - { - $delete = $this->_deleteAll($accounts, $postings); - if (is_a($delete, 'PEAR_Error')) { - return $delete; - } - - /* Log the deletion of this item in the history log. */ - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:' . $this->_ledger . ':all', array('action' => 'delete'), true); - - return true; - } - - /** - * Attempts to return a concrete Fima_Driver instance based on $driver. - * - * @param string $ledger The name of the ledger to load. - * - * @param string $driver The type of the concrete Fima_Driver subclass - * to return. The class name is based on the - * storage driver ($driver). The code is - * dynamically included. - * - * @param array $params (optional) A hash containing any additional - * configuration or connection parameters a - * subclass might need. - * - * @return mixed The newly created concrete Fima_Driver instance, or - * false on an error. - */ - function &factory($ledger = '', $driver = null, $params = null) - { - if ($driver === null) { - $driver = $GLOBALS['conf']['storage']['driver']; - } - $driver = basename($driver); - - if (is_null($params)) { - $params = Horde::getDriverConfig('storage', $driver); - } - - require_once dirname(__FILE__) . '/Driver/' . $driver . '.php'; - $class = 'Fima_Driver_' . $driver; - if (class_exists($class)) { - $fima = new $class($ledger, $params); - $result = $fima->initialize(); - if (is_a($result, 'PEAR_Error')) { - $fima = new Fima_Driver($params, sprintf(_("The Finances backend is not currently available: %s"), $result->getMessage())); - } - } else { - $fima = new Fima_Driver($params, sprintf(_("Unable to load the definition of %s."), $class)); - } - - return $fima; - } - - /** - * Attempts to return a reference to a concrete Fima_Driver - * instance based on $driver. It will only create a new instance - * if no Fima_Driver instance with the same parameters currently - * exists. - * - * This should be used if multiple storage sources are required. - * - * This method must be invoked as: $var = &Fima_Driver::singleton() - * - * @param string $ledger The name of the ledger to load. - * - * @param string $driver The type of concrete Fima_Driver subclass - * to return. The is based on the storage - * driver ($driver). The code is dynamically - * included. - * - * @param array $params (optional) A hash containing any additional - * configuration or connection parameters a - * subclass might need. - * - * @return mixed The created concrete Fima_Driver instance, or false - * on error. - */ - function &singleton($ledger = '', $driver = null, $params = null) - { - static $instances; - - if (is_null($driver)) { - $driver = $GLOBALS['conf']['storage']['driver']; - } - - if (is_null($params)) { - $params = Horde::getDriverConfig('storage', $driver); - } - - if (!isset($instances)) { - $instances = array(); - } - - $signature = serialize(array($ledger, $driver, $params)); - if (!isset($instances[$signature])) { - $instances[$signature] = &Fima_Driver::factory($ledger, $driver, $params); - } - - return $instances[$signature]; - } - -} diff --git a/fima/lib/Driver/sql.php b/fima/lib/Driver/sql.php deleted file mode 100644 index af8765227..000000000 --- a/fima/lib/Driver/sql.php +++ /dev/null @@ -1,1064 +0,0 @@ - - * 'phptype' The database type (e.g. 'pgsql', 'mysql', etc.). - * 'table' The name of the foo table in 'database'. - * 'charset' The database's internal charset. - * - * Required by some database implementations:
- *      'database'      The name of the database.
- *      'hostspec'      The hostname of the database server.
- *      'protocol'      The communication protocol ('tcp', 'unix', etc.).
- *      'username'      The username with which to connect to the database.
- *      'password'      The password associated with 'username'.
- *      'options'       Additional options to pass to the database.
- *      'tty'           The TTY on which to connect to the database.
- *      'port'          The port on which to connect to the database.
- * - * The table structure can be created by the scripts/sql/fima.sql - * script. - * - * Copyright 2007-2008 The Horde Project (http://www.horde.org/) - * - * See the enclosed file COPYING for license information (GPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. - * - * @author Thomas Trethan - * @package Fima - */ -class Fima_Driver_sql extends Fima_Driver { - - /** - * Handle for the current database connection. - * - * @var DB - */ - var $_db; - - /** - * Constructs a new SQL storage object. - * - * @param string $ledger The ledger to load. - * @param array $params A hash containing connection parameters. - */ - function Fima_Driver_sql($ledger, $params = array()) - { - $this->_ledger = $ledger; - $this->_params = $params; - } - - /** - * Retrieves accounts from the database. - * - * @param array $filters Any filters for restricting the retrieved accounts. - * - * @return mixed True on success, PEAR_Error on failure. - */ - function retrieveAccounts($filters = array()) - { - /* Build the SQL query. */ - $query = sprintf('SELECT * FROM %s WHERE account_owner = ?', $this->_params['table_accounts']); - $values = array($this->_ledger); - - /* Add filters. */ - $this->_addFilters($filters, $query, $values, 'account_'); - - /* Sorting. */ - $query .= ' ORDER BY account_number ASC'; - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::retrieveAccounts(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $this->_accounts = array(); - $result = $this->_db->query($query, $values); - - if (isset($result) && !is_a($result, 'PEAR_Error')) { - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - - /* Store the retrieved values in the accounts variable. */ - $this->_accounts = array(); - while ($row && !is_a($row, 'PEAR_Error')) { - /* Add this new account to the $_account list. */ - $this->_accounts[$row['account_id']] = $this->_buildAccount($row); - - /* Advance to the new row in the result set. */ - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - } - $result->free(); - } else { - return $result; - } - - return true; - } - - /** - * Retrieves one account from the database. - * - * @param string $accountId The ID of the account to retrieve. - * - * @return array The array of account attributes. - */ - function getAccount($accountId) - { - /* Build the SQL query. */ - $query = sprintf('SELECT * FROM %s WHERE account_owner = ? AND account_id = ?', - $this->_params['table_accounts']); - $values = array($this->_ledger, $accountId); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::getAccount(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - if ($row === null) { - return PEAR::raiseError(_("Not found")); - } - - /* Decode and return the account. */ - return $this->_buildAccount($row); - } - - /** - * Retrieves one account from the database by number. - * - * @param string $number The number of the account to retrieve. - * - * @return array The array of account attributes. - */ - function getAccountByNumber($number) - { - /* Build the SQL query. */ - $query = sprintf('SELECT * FROM %s WHERE account_owner = ? AND account_number = ?', - $this->_params['table_accounts']); - $values = array($this->_ledger, sprintf('%\'04s', $number)); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::getAccountByNumber(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - if ($row === null) { - return PEAR::raiseError(_("Not found")); - } - - /* Decode and return the account. */ - return $this->_buildAccount($row); - } - - /** - * Retrieves postings from the database. - * - * @param array $filters Any filters for restricting the retrieved postings. - * @param array $sorting Sort order of retrieved postings. - * @param array $limit Limit of the retrieved postings, array(page, postings/page). - * - * @return mixed True on success, PEAR_Error on failure. - */ - function retrievePostings($filters = array(), $sorting = array(), $limit = array()) - { - /* Build the SQL query filter. */ - $queryfilter = ' WHERE posting_owner = ?'; - $values = array($this->_ledger); - - /* Add filters. */ - $this->_addFilters($filters, $queryfilter, $values, 'posting_'); - - $query = sprintf('SELECT count(p.posting_id) posting_count, SUM(p.posting_amount) posting_result FROM %s p', - $this->_params['table_postings']); - $query .= $queryfilter; - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::retrievePostings(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $result = $this->_db->query($query, $values); - if (isset($result) && !is_a($result, 'PEAR_Error')) { - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - $this->_postingsCount = (int)$row['posting_count']; - $this->_postingsResult = $row['posting_result']; - $result->free(); - - // correct result when account is an asset account too - if ($this->_postingsCount > 0) { - $query = sprintf('SELECT SUM(p.posting_amount) posting_result ' . - 'FROM %s p JOIN %s a ON a.account_id = p.posting_account ' . - $queryfilter . ' AND a.account_type = ?', - $this->_params['table_postings'], $this->_params['table_accounts']); - $values2 = $values; - $values2[] = FIMA_ACCOUNTTYPE_ASSET; - $result = $this->_db->query($query, $values2); - if (isset($result) && !is_a($result, 'PEAR_Error')) { - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - } - $this->_postingsResult -= $row['posting_result']; - $result->free(); - } - } else { - return $result; - } - - /* Fetch the postings if necessary. */ - $this->_postings = array(); - if ($this->_postingsCount == 0) { - return true; - } - - $query = sprintf('SELECT p.*, asset.account_number posting_asset_number, account.account_number posting_account_number ' . - 'FROM %s p LEFT OUTER JOIN %s asset ON p.posting_asset = asset.account_id LEFT OUTER JOIN %s account ON p.posting_account = account.account_id', - $this->_params['table_postings'], $this->_params['table_accounts'], $this->_params['table_accounts']); - $query .= $queryfilter; - - /* Sorting. */ - if (!is_array($sorting)) { - $sorting = array($sorting); - } - if (count($sorting) == 0) { - $sorting = array('posting_date ASC'); - } - $query .= ' ORDER BY ' . implode(', ', $sorting); - - /* Limit. */ - if (count($limit) > 0) { - if ($limit[0] < 0) { - $limit[0] += ceil($this->_postingsCount / $limit[1]) + 1; - } - $limit[0] = ($limit[0] - 1) * $limit[1]; - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::retrievePostings() limitQuery: %s', $query), 'DEBUG'); - $result = $this->_db->queryLimit($query, $limit[0], $limit[1], $values); - } else { - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::retrievePostings(): %s', $query), 'DEBUG'); - $result = $this->_db->query($query, $values); - } - - /* Execute the query. */ - $result = $this->_db->query($query, $values); - if (isset($result) && !is_a($result, 'PEAR_Error')) { - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - - /* Store the retrieved values in the accounts variable. */ - while ($row && !is_a($row, 'PEAR_Error')) { - /* Add this new posting to the $_posting list. */ - $this->_postings[$row['posting_id']] = $this->_buildPosting($row); - - /* Advance to the new row in the result set. */ - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - } - $result->free(); - } else { - return $result; - } - - return true; - } - - /** - * Retrieves one posting from the database. - * - * @param string $postingId The ID of the posting to retrieve. - * - * @return array The array of posting attributes. - */ - function getPosting($postingId) - { - /* Build the SQL query. */ - $query = sprintf('SELECT * FROM %s WHERE posting_owner = ? AND posting_id = ?', - $this->_params['table_postings']); - $values = array($this->_ledger, $postingId); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::getPosting(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $result = $this->_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - if ($row === null) { - return PEAR::raiseError(_("Not found")); - } - - /* Decode and return the posting. */ - return $this->_buildPosting($row); - } - - /** - * Get grouped results. - * - * @param array $groups Fields to group. - * @param boolean $filters Filters for postings. - * - * @return array A matrix of the grouped results. - */ - function getResults($groups, $filters = array()) { - $matrix = array(); - - /* Fix grouping. */ - if (!is_array($groups)) { - $groups = array($groups); - } - if (!isset($groups[1])) { - $groups[1] = 'owner'; - } - foreach ($groups as $groupId => $group) { - switch($group) { - case 'date_month': $groups[$groupId] = 'FROM_UNIXTIME(posting_date, \'%Y%m\')'; break; - case 'date_year': $groups[$groupId] = 'FROM_UNIXTIME(posting_date, \'%Y\')'; break; - case 'asset_number': $groups[$groupId] = 'asset.account_number'; break; - case 'asset_parent': $groups[$groupId] = 'CONCAT(LEFT(asset.account_number, 2), \'00\')'; break; - case 'asset_type': $groups[$groupId] = 'asset.account_type'; break; - case 'account_number': $groups[$groupId] = 'account.account_number'; break; - case 'account_parent': $groups[$groupId] = 'CONCAT(LEFT(account.account_number, 2), \'00\')'; break; - case 'account_type': $groups[$groupId] = 'account.account_type'; break; - default: $groups[$groupId] = 'posting_'.$group; break; - } - } - - /* Build the SQL query filter. */ - $query = sprintf('SELECT %s x, %s y, sum(posting_amount) result ' . - 'FROM %s p LEFT OUTER JOIN %s asset ON p.posting_asset = asset.account_id AND p.posting_owner = asset.account_owner LEFT OUTER JOIN %s account ON p.posting_account = account.account_id AND p.posting_owner = account.account_owner ' . - 'WHERE posting_owner = ?', - $groups[0], $groups[1], $this->_params['table_postings'], $this->_params['table_accounts'], $this->_params['table_accounts']); - $values = array($this->_ledger); - - /* Add filters. */ - foreach ($filters as $filterId => $filter) { - switch($filter[0]) { - case 'date_month': $filters[$filterId][0] = 'FROM_UNIXTIME(posting_date, \'%Y%m\')'; break; - case 'date_year': $filters[$filterId][0] = 'FROM_UNIXTIME(posting_date, \'%Y%m\')'; break; - case 'asset_number': $filters[$filterId][0] = 'asset.account_number'; break; - case 'asset_parent': $filters[$filterId][0] = 'LEFT(asset.account_number, 2)'; break; - case 'asset_type': $filters[$filterId][0] = 'asset.account_type'; break; - case 'account_number': $filters[$filterId][0] = 'account.account_number'; break; - case 'account_parent': $filters[$filterId][0] = 'LEFT(account.account_number, 2)'; break; - case 'account_type': $filters[$filterId][0] = 'account.account_type'; break; - default: $filters[$filterId][0] = 'posting_'.$filter[0]; break; - } - } - $this->_addFilters($filters, $query, $values); - - /* Add grouping. */ - $query .= ' GROUP BY ' . implode(', ', $groups); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::getResults(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $result = $this->_db->query($query, $values); - if (isset($result) && !is_a($result, 'PEAR_Error')) { - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - - /* Store the retrieved values in the accounts variable. */ - while ($row && !is_a($row, 'PEAR_Error')) { - /* Add this new posting to the $_posting list. */ - if (!isset($matrix[$row['y']])) { - $matrix[$row['y']] = array(); - } - $matrix[$row['y']][$row['x']] = $row['result']; - - /* Advance to the new row in the result set. */ - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - } - $result->free(); - } - - return $matrix; - } - - /** - * Get the results of all asset accounts. - * - * @param string $postingtype Type of postings. - * @param boolean $perdate Date of asset results. - * - * @return array Array of asset accounts and results - */ - function getAssetResults($postingtype, $perdate = null) - { - $perdate = ($perdate === null) ? mktime() : (int)$perdate; - - /* Build the SQL query. */ - $query = sprintf('SELECT account_id, SUM(account_result) account_result FROM ( ' . - ' SELECT a1.account_id, SUM(p1.posting_amount) account_result ' . - ' FROM %s a1 LEFT OUTER JOIN %s p1 ON a1.account_id = p1.posting_asset AND p1.posting_owner = ? AND p1.posting_type = ? ' . - ' WHERE a1.account_owner = ? AND a1.account_type = ? and p1.posting_date <= ?' . - ' GROUP BY a1.account_id ' . - ' UNION ' . - ' SELECT a2.account_id, SUM(p2.posting_amount) * -1 account_result ' . - ' FROM %s a2 LEFT OUTER JOIN %s p2 ON a2.account_id = p2.posting_account AND p2.posting_owner = ? AND p2.posting_type = ? ' . - ' WHERE a2.account_owner = ? AND a2.account_type = ? and p2.posting_date <= ?' . - ' GROUP BY a2.account_id ' . - ') x ' . - 'GROUP BY account_id ', - $this->_params['table_accounts'], $this->_params['table_postings'], - $this->_params['table_accounts'], $this->_params['table_postings']); - $values = array($this->_ledger, $postingtype, $this->_ledger, FIMA_ACCOUNTTYPE_ASSET, $perdate, - $this->_ledger, $postingtype, $this->_ledger, FIMA_ACCOUNTTYPE_ASSET, $perdate); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::getAssetResults(): %s', $query), 'DEBUG'); - - /* Execute the query. */ - $assetresults = array(); - $result = $this->_db->query($query, $values); - if (isset($result) && !is_a($result, 'PEAR_Error')) { - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - if (is_a($row, 'PEAR_Error')) { - return $row; - } - - /* Store the retrieved values in the accounts variable. */ - while ($row && !is_a($row, 'PEAR_Error')) { - /* Add this new posting to the $_posting list. */ - $assetresults[] = $row; - - /* Advance to the new row in the result set. */ - $row = $result->fetchRow(DB_FETCHMODE_ASSOC); - } - $result->free(); - } else { - return $result; - } - - return $assetresults; - } - - /** - * Build an account. - * - * @param array $row Datasbase row holding account attributes. - * @param boolean $getparent Also get parent account. - * - * @return array The array of account attributes. - */ - function _buildAccount($row, $getparent = true) - { - $parent = null; - if ($getparent) { - if (($parent_number = Fima::getAccountParent($row['account_number'])) !== null) { - if (isset($this->_accounts[$parent_number])) { - $parent = $this->_accounts[$parent_number]; - } else { - $parent = $this->getAccountByNumber($parent_number); - if (is_a($parent, 'PEAR_Error')) { - $parent = null; - } - } - } - } - - /* Create a new account based on $row's values. */ - return array('account_id' => $row['account_id'], - 'owner' => $row['account_owner'], - 'number' => sprintf('%\'04d', $row['account_number']), - 'type' => $row['account_type'], - 'name' => Horde_String::convertCharset($row['account_name'], $this->_params['charset']), - 'eo' => $row['account_eo'], - 'desc' => Horde_String::convertCharset($row['account_desc'], $this->_params['charset']), - 'closed' => $row['account_closed'], - 'label' => trim($row['account_number'] . ' ' . - (($parent === null) ? '' : $parent['name'] . ' - ') . - Horde_String::convertCharset($row['account_name'], $this->_params['charset'])), - 'parent_id' => ($parent === null) ? null : $parent['account_id'], - 'parent_number' => ($parent === null) ? '' : $parent['number'], - 'parent_name' => ($parent === null) ? '' : $parent['name']); - } - - /** - * Adds an account to the backend storage. - * - * @param string $number The number of the account. - * @param string $type The type of the account. - * @param string $name The name (short) of the account. - * @param boolean $eo Extraordinary account. - * @param string $desc The description (long) of the account. - * @param boolean $closed Close account. - * - * @return mixed ID of the new account or PEAR_Error - */ - function _addAccount($number, $type, $name, $eo, $desc, $closed) - { - $accountId = strval(new Horde_Support_Uuid()); - - $query = sprintf( - 'INSERT INTO %s (account_id, account_owner, account_number, account_type, ' . - 'account_name, account_eo, account_desc, account_closed) ' . - 'VALUES (?, ?, ?, ?, ?, ?, ?, ?)', - $this->_params['table_accounts']); - $values = array($accountId, - $this->_ledger, - sprintf('%\'04d', $number), - $type, - Horde_String::convertCharset($name, $GLOBALS['registry']->getCharset(), $this->_params['charset']), - (int)(bool)$eo, - Horde_String::convertCharset($desc, $GLOBALS['registry']->getCharset(), $this->_params['charset']), - (int)(bool)$closed); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_addAccount(): %s', $query), 'DEBUG'); - - /* Attempt the insertion query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return $accountId; - } - - /** - * Modifies an existing account. - * - * @param string $accountId The account to modify. - * @param string $number The number of the account. - * @param string $type The type of the account. - * @param string $name The name (short) of the account. - * @param boolean $eo Extraordinary account. - * @param string $desc The description (long) of the account. - * @param boolean $closed Close account. - * - * @return mixed True or PEAR_Error - */ - function _modifyAccount($accountId, $number, $type, $name, $eo, $desc, $closed) - { - $query = sprintf('UPDATE %s SET' . - ' account_number = ?, ' . - ' account_type = ?, ' . - ' account_name = ?, ' . - ' account_eo = ?, ' . - ' account_desc = ?, ' . - ' account_closed = ? ' . - 'WHERE account_owner = ? AND account_id = ?', - $this->_params['table_accounts']); - $values = array(sprintf('%\'04d', $number), - $type, - Horde_String::convertCharset($name, $GLOBALS['registry']->getCharset(), $this->_params['charset']), - (int)(bool)$eo, - Horde_String::convertCharset($desc, $GLOBALS['registry']->getCharset(), $this->_params['charset']), - (int)(bool)$closed, - $this->_ledger, - $accountId); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_modifyAccount(): %s', $query), 'DEBUG'); - - /* Attempt the update query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return true; - } - - /** - * Deletes an account from the backend. - * - * @param string $accountId The account to delete. - * @param mixed $dsSubaccounts True/false when deleting subaccounts, - * accountId when shifting subaccounts - * @param mixed $dsPostings True/false when deleting postings, - * accountId when shifting postings - * - * @return mixed True or PEAR_Error - */ - function _deleteAccount($accountId, $dsSubaccounts = false, $dsPostings = true) - { - /* Get the account's details for use later. */ - $account = $this->getAccount($accountId); - - /* Handle subaccounts. */ - if ($dsSubaccounts !== false) { - /* Delete subaccounts. */ - $parent = (int)($account['number'] / 100) . '%'; - $this->retrieveAccounts(array(array('number', $parent, 'LIKE'), - array('number', (string)$account['number'], '!='))); - - foreach ($this->_accounts as $subaccountId => $subaccount) { - $delete = $this->_deleteAccount($subaccountId, false, $dsSubaccounts); - if (is_a($delete, 'PEAR_Error')) { - return $delete; - } - } - } - - /* Handle postings. */ - if ($dsPostings !== false) { - if ($dsPostings === true) { - /* Delete account postings. */ - $query = sprintf('DELETE FROM %s WHERE posting_owner = ? AND (posting_asset = ? OR posting_account = ?)', - $this->_params['table_postings']); - $values = array($this->_ledger, $accountId, $accountId); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_deleteAccount(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } else { - /* Shift account postings. */ - $shift = $this->_shiftPostings($accountId, $dsPostings); - if (is_a($shift, 'PEAR_Error')) { - return $shift; - } - } - } - - /* Delete account. */ - $query = sprintf('DELETE FROM %s WHERE account_owner = ? AND account_id = ?', - $this->_params['table_accounts']); - $values = array($this->_ledger, $accountId); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_deleteAccount(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return true; - } - - /** - * Build a posting. - * - * @param array $row Datasbase row holding posting attributes; - * - * @return array The array of posting attributes. - */ - function _buildPosting($row) - { - /* Create a new account based on $row's values. */ - return array('posting_id' => $row['posting_id'], - 'owner' => $row['posting_owner'], - 'type' => $row['posting_type'], - 'date' => $row['posting_date'], - 'asset' => $row['posting_asset'], - 'account' => $row['posting_account'], - 'desc' => Horde_String::convertCharset($row['posting_desc'], $this->_params['charset']), - 'amount' => $row['posting_amount'], - 'eo' => (int)(bool)$row['posting_eo']); - } - - /** - * Adds a posting to the backend storage. - * - * @param string $type The posting type. - * @param integer $date The posting date. - * @param string $asset The ID of the asset account. - * @param string $account The ID of the account. - * @param boolean $eo Extraordinary posting. - * @param float $amount The posting amount. - * @param string $desc The posting description. - * - * @return mixed ID of the new posting or PEAR_Error - */ - function _addPosting($type, $date, $asset, $account, $eo, $amount, $desc) - { - $postingId = strval(new Horde_Support_Uuid()); - - $query = sprintf( - 'INSERT INTO %s (posting_id, posting_owner, posting_type, posting_date, ' . - 'posting_asset, posting_account, posting_eo, posting_amount, posting_desc) ' . - 'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', - $this->_params['table_postings']); - $values = array($postingId, - $this->_ledger, - $type, - (int)$date, - $asset, - $account, - (int)(bool)$eo, - (float)$amount, - Horde_String::convertCharset($desc, $GLOBALS['registry']->getCharset(), $this->_params['charset'])); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_addPosting(): %s', $query), 'DEBUG'); - - /* Attempt the insertion query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return $postingId; - } - - /** - * Modifies an existing posting. - * - * @param string $postingId The posting to modify. - * @param string $type The posting type. - * @param integer $date The posting date. - * @param string $asset The ID of the asset account. - * @param string $account The ID of the account. - * @param boolean $eo Extraordinary posting. - * @param float $amount The posting amount. - * @param string $desc The posting description. - * - * @return mixed True or PEAR_Error - */ - function _modifyPosting($postingId, $type, $date, $asset, $account, $eo, $amount, $desc) - { - $query = sprintf('UPDATE %s SET' . - ' posting_type = ?, ' . - ' posting_date = ?, ' . - ' posting_asset = ?, ' . - ' posting_account = ?, ' . - ' posting_eo = ?, ' . - ' posting_amount = ?, ' . - ' posting_desc = ? ' . - 'WHERE posting_owner = ? AND posting_id = ?', - $this->_params['table_postings']); - $values = array($type, - (int)$date, - $asset, - $account, - (int)(bool)$eo, - (float)$amount, - Horde_String::convertCharset($desc, $GLOBALS['registry']->getCharset(), $this->_params['charset']), - $this->_ledger, - $postingId); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_modifyPosting(): %s', $query), 'DEBUG'); - - /* Attempt the update query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return true; - } - - /** - * Deletes a posting from the backend. - * - * @param string $postingId The posting to delete. - * - * @return mixed True or PEAR_Error - */ - function _deletePosting($postingId) - { - /* Get the task's details for use later. */ - $posting = $this->getPosting($postingId); - - $query = sprintf('DELETE FROM %s WHERE posting_owner = ? AND posting_id = ?', - $this->_params['table_postings']); - $values = array($this->_ledger, $postingId); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_deletePosting(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return true; - } - - /** - * Shift an existing posting. - * - * @param string $postingId The posting to shift. - * @param string $type The posting type shifting to. - * @param string $asset The ID of the asset account. - * @param string $account The ID of the account. - * - * @return mixed True or PEAR_Error - */ - function _shiftPosting($postingId, $type, $asset, $account) - { - if (!$type && !$asset && !$account) { - return true; - } - - $query = sprintf('UPDATE %s SET' . - ($type ? ' posting_type = ?, ' : '') . - ($asset ? ' posting_asset = ?, ' : '') . - ($account ? ' posting_account = ?, ' : ''). - ' posting_eo = posting_eo ' . - 'WHERE posting_owner = ? AND posting_id = ?', - $this->_params['table_postings']); - $values = array(); - if ($type) { $values[] = $type; } - if ($asset) { $values[] = $asset; } - if ($account) { $values[] = $account; } - $values[] = $this->_ledger; - $values[] = $postingId; - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_shiftPosting(): %s', $query), 'DEBUG'); - - /* Attempt the update query. */ - $result = $this->_db->query($query, $values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return true; - } - - /** - * Shift postings in the backend. - * - * @param mixed $accountIdFrom The account(s) to shift postings from. - * @param string $accountIdTo The account to shift postings to. - * - * @return mixed True or PEAR_Error - */ - function _shiftPostings($accountIdFrom, $accountIdTo) - { - if (!is_array($accountIdFrom)) { - $accountIdFrom = array($accountIdFrom); - } - - foreach ($accountIdFrom as $key => $value) { - $accountIdFrom[$key] = $this->_db->quoteSmart($value); - } - - $fields = array('posting_asset', 'posting_account'); - foreach ($fields as $field) { - $query = sprintf('UPDATE %s SET' . - ' %s = ? ' . - 'WHERE posting_owner = ? AND %s IN (!)', - $this->_params['table_postings'], $field, $field); - $values = array($accountIdTo, $this->_ledger, implode(',', $accountIdFrom)); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_shiftPostings(): %s', $query), 'DEBUG'); - - /* Attempt the update query. */ - $result = $this->_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } - - return true; - } - - /** - * Deletes all postings and accounts. - * - * @param mixed $accounts boolean or account_type - * @param mixed $accounts boolean or posting_type. - * - * @return mixed True or PEAR_Error - */ - function _deleteAll($accounts, $postings) - { - /* Delete postings. */ - if ($postings) { - $query = sprintf('DELETE FROM %s WHERE posting_owner = ?', - $this->_params['table_postings']); - $values = array($this->_ledger); - - /* Filter. */ - if ($postings !== true) { - $query .= ' AND posting_type = ?'; - $values[] = $postings; - } - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_deleteAll(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } else { - /* If postings aren't deleted, don't delete accounts. */ - return false; - } - - /* Delete Accounts */ - if ($accounts) { - $query = sprintf('DELETE FROM %s WHERE account_owner = ?', - $this->_params['table_accounts']); - $values = array($this->_ledger); - - /* Filter. */ - if ($accounts !== true) { - $query .= ' AND account_type = ?'; - $values[] = $accounts; - } - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Fima_Driver_sql::_deleteAll(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } - - return true; - } - - - /** - * Build the where clause for a query using the passed filters - * Attention: does not include the WHERE keyword, add WHERE 1=1 manually in the query - * - * @param array $filters Array of filters, syntax: array(field, value [, operator = '=' [, andor = 'AND']]) - * @param array $prefix optional prefix for fields - * - * @return integer number of added filters - */ - function _addFilters($filters, &$query, &$values, $prefix = '') - { - $filtercnt = 0; - - foreach ($filters as $filter) { - // and/or - if (!isset($filter[3])) { - $filter[3] = 'AND'; - } else { - $filter[3] = strtoupper($filter[3]); - if (!in_array($filter[3], array('AND', 'OR'))) { - $filter[3] = 'AND'; - } - } - - // subfilter - if (is_array($filter[0])) { - $query .= ' ' . $filter[3] . ' (1=1'; - $filtercnt += $this->_addFilters($filter[0], $query, $values, $prefix); - $query .= ')'; - continue; - } - - // fix operator - if (!isset($filter[2])) { - $filter[2] = '='; - } else { - $filter[2] = strtoupper($filter[2]); - if (!in_array($filter[2], array('<', '>', '<=', '>=', '=', '<>', '!=', 'IN', 'NOT IN', 'IS', 'IS NOT', 'LIKE', 'NOT LIKE'))) { - $filter[2] = '='; - } - } - - // fix operator for null values - if ($filter[1] === null) { - if (!in_array($filter[2], array('IS', 'IS NOT'))) { - $filter[2] = in_array($filter[2], array('=', 'IN', 'LIKE')) ? 'IS' : 'IS NOT'; - } - } elseif (in_array($filter[2], array('IS', 'IS NOT'))) { - $filter[2] = ($filter[2] == 'IS') ? '=' : '!='; - } - - // fix operator for array value + prepare values - if (is_array($filter[1])) { - if (!in_array($filter[2], array('IN', 'NOT IN'))) { - $filter[2] = in_array($filter[2], array('=', 'IS', 'LIKE')) ? 'IN' : 'NOT IN'; - } - $filterph = '(!)'; - foreach ($filter[1] as $key => $value) { - $filter[1][$key] = $this->_db->quoteSmart($value); - } - $filter[1] = implode(',', $filter[1]); - } else { - if (in_array($filter[2], array('IN', 'NOT IN'))) { - $filter[2] = ($filter[2] == 'IN') ? '=' : '!='; - } - $filterph = '?'; - } - - // fix != operator - if ($filter[2] == '!=') { - $filter[2] = '<>'; - } - - $query .= sprintf(' ' . $filter[3] . ' ' . $prefix . '%s %s %s', $filter[0], $filter[2], $filterph); - $values[] = $filter[1]; - $filtercnt++; - } - - return $filtercnt; - } - - /** - * Attempts to open a connection to the SQL server. - * - * @return boolean True on success; PEAR_Error on failure. - */ - function initialize() - { - try { - $this->_db = $GLOBALS['injector']->getInstance('Horde_Db_Pear')->getDb('rw', 'fima', 'storage'); - } catch (Horde_Exception $e) { - return PEAR::raiseError($e->getMessage()); - } - - return true; - } - -} diff --git a/fima/lib/Fima.php b/fima/lib/Fima.php deleted file mode 100644 index 98a55f4d7..000000000 --- a/fima/lib/Fima.php +++ /dev/null @@ -1,764 +0,0 @@ - - * @package Fima - */ -class Fima { - - /** - * Retrieves the current user's ledgers from storage. - * This function will also sort the resulting list, if requested. - * - * @param boolean $filters Filters for accounts. - * - * @return array A list of the requested accounts. - * - * @see Fima_Driver::listAccounts() - */ - function listAccounts($filters = array()) - { - $ledger = Fima::getActiveLedger(); - - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - $storage->retrieveAccounts($filters); - - /* Retrieve the accounts from storage. */ - $accounts = $storage->listAccounts(); - if (is_a($accounts, 'PEAR_Error')) { - return $accounts; - } - - return $accounts; - } - - function getAccount($account) - { - $ledger = Fima::getActiveLedger(); - $storage = &Fima_Driver::singleton($ledger); - return $storage->getAccount($account); - } - - /** - * Retrieves the current user's postings from storage. - * - * @param boolean $filters Filters for postings. - * @param integer $page Page/Recordsset to display. - * - * @return array A list of the requested postings. - * - * @see Fima_Driver::listPostings() - */ - function listPostings($filters = array(), $page = null) - { - global $prefs; - - $ledger = Fima::getActiveLedger(); - $postingtype = $prefs->getValue('active_postingtype'); - if ($page == 0) { - $limit = null; - } else { - $limit = array($page, (int)$prefs->getValue('max_postings')); - } - - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - $storage->retrievePostings($filters, - array('posting_' . $prefs->getValue('sortby') . ' ' . ($prefs->getValue('sortdir') ? 'DESC' : 'ASC'), - 'posting_' . $prefs->getValue('altsortby')), - $limit); - - /* Retrieve the accounts from storage. */ - $postings = $storage->listPostings(); - if (is_a($postings, 'PEAR_Error')) { - return $postings; - } - - return $postings; - } - - /** - * Get the total number of postings with the selected filters. - * - * @return int The total number of postings. - */ - function getPostingsCount() - { - $ledger = Fima::getActiveLedger(); - - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - return $storage->_postingsCount; - } - - - /** - * Get grouped results from storage. - * - * @param array $groups Fields to group. - * @param boolean $filters Filters for postings. - * - * @return array A matrix of the grouped results. - * - * @see Fima_Driver::listPostings() - */ - function getResults($groups = array(), $filters = array()) { - $ledger = Fima::getActiveLedger(); - - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - return $storage->getResults($groups, $filters); - } - - /** - * Get the results of all asset accounts. - * - * @param string $postingtype Type of postings. - * @param boolean $perdate Date of asset results. - * - * @return array Array of asset accounts and results - */ - function getAssetResults($postingtype, $perdate = null) - { - $ledger = Fima::getActiveLedger(); - - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - return $storage->getAssetResults($postingtype, $perdate); - } - - /** - * Get the total result of postings with the selected filters. - * - * @return float The total result of postings. - */ - function getPostingsResult() - { - $ledger = Fima::getActiveLedger(); - - /* Create a Fima storage instance. */ - $storage = &Fima_Driver::singleton($ledger); - return $storage->_postingsResult; - } - - /** - * Lists all ledgers a user has access to. - * - * @param boolean $owneronly Only return ledgers that this user owns? - * Defaults to false. - * @param integer $permission The permission to filter ledgers by. - * - * @return array The list of ledgers. - */ - function listLedgers($owneronly = false, $permission = Horde_Perms::SHOW) - { - $ledgers = $GLOBALS['fima_shares']->listShares($GLOBALS['registry']->getAuth(), $permission, $owneronly ? $GLOBALS['registry']->getAuth() : null); - if (is_a($ledgers, 'PEAR_Error')) { - Horde::logMessage($ledgers, 'ERR'); - return array(); - } - - return $ledgers; - } - - /** - * Returns the active ledger for the current user. - */ - function getActiveLedger($permission = Horde_Perms::SHOW) - { - global $prefs; - - $active_ledger = $prefs->getValue('active_ledger'); - $ledgers = Fima::listLedgers(false, $permission); - - if (isset($ledgers[$active_ledger])) { - return $active_ledger; - } elseif ($prefs->isLocked('active_ledger')) { - return false; - } elseif (count($ledgers)) { - return key($ledgers); - } - - return false; - } - - /** - * Get parent account number - */ - function getAccountParent($accountNumber) - { - if ($accountNumber % 100 == 0) { - $parent = null; - } else { - $parent = sprintf('%\'04d', (int)($accountNumber / 100) * 100); - } - return $parent; - } - - /** - * Builds the HTML for a account selection widget. - * - * @param string $name The name of the widget. - * @param mixed $value The value(s) to select by default. - * @param string $params Any additional parameters to include in the widget. - */ - function buildAccountWidget($name, $value = '', $params = null, $blank = false, $multiple = false, $filters = array(), $hideclosed = false) - { - $accounts = Fima::listAccounts($filters); - - $html = '\n"; - } - - /** - * Builds the HTML for a account type selection widget. - * - * @param string $name The name of the widget. - * @param string $value The value to select by default. - * @param string $params Any additional parameters to include in the widget. - */ - function buildAccountTypeWidget($name, $value = '', $params = null, $blank = false, $multiple = false) - { - $types = Fima::getAccountTypes(); - - $html = '\n"; - } - - /** - * Builds the HTML for a posting type selection widget. - * - * @param string $name The name of the widget. - * @param string $value The value to select by default. - * @param string $params Any additional parameters to include in the widget. - */ - function buildPostingTypeWidget($name, $value = '', $params = null, $blank = false, $multiple = false) - { - $types = Fima::getPostingTypes(); - - $html = '\n"; - } - - /** - * Builds the HTML for a date selection widget. - * - * @param string $name The name of the widget. - * @param integer $value The value to select by default. - * @param string $params Any additional parameters to include in the widget. - */ - function buildDateWidget($name, $value = 0, $params = null, $blank = false, $periodonly = false) - { - $value = ($value !== 0) ? explode('-', date('Y-n-j', $value)) : array(date('Y'), 0, 0); - - /* Year. */ - $html = ''; - } - for ($i = 1; $i < 13; ++$i) { - $html .= ''; - } - $html .= '' . "\n"; - - /* Period only? */ - if ($periodonly) { - return $html; - } - - /* Day. */ - $html .= '- ' . "\n"; - - return $html; - } - - /** - * Get account types. - * - * @param string $accountType Get a specific account type or all. - * - * @return mixed Array of account types or a specific account type. - */ - function getAccountTypes($accountType = null) - { - $types = array(FIMA_ACCOUNTTYPE_ASSET => _("Asset"), - FIMA_ACCOUNTTYPE_INCOME => _("Income"), - FIMA_ACCOUNTTYPE_EXPENSE => _("Expense")); - - if ($accountType !== null) { - if (isset($types[$accountType])) { - return $types[$accountType]; - } else { - return null; - } - } else { - return $types; - } - } - - /** - * Get posting types. - * - * @param string $postingType Get a specific posting type or all. - * - * @return mixed Array of posting types or a specific posting type. - */ - function getPostingTypes($postingType = null) - { - $types = array(FIMA_POSTINGTYPE_ACTUAL => _("Actual"), - FIMA_POSTINGTYPE_FORECAST => _("Forecast"), - FIMA_POSTINGTYPE_BUDGET => _("Budget")); - - if ($postingType !== null) { - if (isset($types[$postingType])) { - return $types[$postingType]; - } else { - return null; - } - } else { - return $types; - } - } - - /** - * Convert an amount from the interface to a float value. - * - * @param string $amount Amount to convert. - * - * @return float Float value of the amount. - */ - function convertAmountToValue($amount) - { - global $prefs; - - $format = $prefs->getValue('amount_format'); - return (float)str_replace(array($format{0}, $format{1}), array('', '.'), $amount); - } - - /** - * Convert a float number to an amount for the interface. - * - * @param float $value Float value to convert. - * - * @return string Amount. - */ - function convertValueToAmount($value) - { - global $prefs; - - $format = $prefs->getValue('amount_format'); - return number_format($value, 2, $format{1}, $format{0}); - } - - /* - * Convert a formatted date to a unix timestamp. - * - * @param string $date Formatted date. - * @param string $format Date format. - * - * @return int Unix timestamp. - */ - function convertDateToStamp($date, $format) - { - if ($date == '') { - return false; - } - - if (preg_match('/[^%a-zA-Z]/', $format, $seperator) === false) { - return false; - } - - $formatparts = explode($seperator[0], $format); - $dateparts = explode($seperator[0], $date); - - foreach ($formatparts as $key => $fmt) { - $dateparts[$fmt] = $dateparts[$key]; - } - - $stamp = mktime(0, 0, 0, $dateparts['%m'], $dateparts['%d'], $dateparts['%Y']); - - return $stamp; - } - - /** - * Convert a date format to a format useable when entering postings. - * - * @param string $format Date format. - * - * @return string The converted date format. - */ - function convertDateFormat($format) - { - switch($format) { - case '%x': - case '%Y-%m-%d': - case '%d/%m/%Y': - case '%d.%m.%Y': - case '%m/%d/%Y': - break; - case '%a %Y-%m-%d': - $format = '%Y-%m-%d'; - break; - case '%A, %d %B %Y': - case '%a, %e %b %Y': - case '%a, %e %b %y': - case '%a %d %b %Y': - case '%e %b %Y': - case '%e. %m %Y': - $format = '%d/%m/%Y'; - break; - case '%A, %d. %B %Y': - case '%e. %b %Y': - case '%e. %m.': - case '%e. %B': - case '%e. %B %Y': - case '%e. %B %y': - $format = '%d.%m.%Y'; - break; - case '%A %B %d, %Y': - case '%a, %b %e, %Y': - case '%a, %b %e, %y': - case '%a, %b %e': - case '%B %e, %Y': - $format = '%m/%d/%Y'; - break; - case '%a %x': - default: - $format = '%x'; - break; - } - - if ($format == '%x') { - $fmts = array('%Y-%m-%d', '%d/%m/%Y', '%d.%m.%Y', '%m/%d/%Y'); - foreach ($fmts as $fmt) { - if (strftime($format) == strftime($fmt)) { - $format = $fmt; - break; - } - } - if ($format == '%x') { - $format = $fmts[0]; - } - } - - return $format; - } - - /** - * Convert a date format to a period format useable for reports. - * - * @param string $format Date format. - * - * @return string The converted period format. - */ - function convertDateToPeriodFormat($format) - { - if ($format == '%x') { - $fmts = array('%Y-%m-%d', '%d/%m/%Y', '%d.%m.%Y', '%m/%d/%Y'); - foreach ($fmts as $fmt) { - if (strftime($format) == strftime($fmt)) { - $format = $fmt; - break; - } - } - if ($format == '%x') { - $format = $fmts[0]; - } - } - $format .= ' '; - - $p = preg_match_all('/(%[YymBb])(.)/', $format, $matches); - $format = ''; - for ($i = 0; $i < $p; $i++) { - $format .= $matches[1][$i] . (($i < $p - 1) ? $matches[2][$i] : ''); - } - - return $format; - } - - /** - * Convert wildcards in a text to SQL wildcards. - * - * @param string $text Text containing wildcards. - * - * @return string Converted text with SQL wildcards. - */ - function convertWildcards($text) - { - global $prefs; - - $wildcards = $prefs->getValue('wildcard_format'); - if ($wildcards == 'dos') { - $text = str_replace(array('\\*', '\\?'), array(chr(0xe), chr(0xf)), $text); - $text = str_replace(array('%', '_'), array('\\%', '\\_'), $text); - $text = str_replace(array('*', '?'), array('%', '_'), $text); - $text = str_replace(array(chr(0xe), chr(0xf)), array('*', '?'), $text); - } elseif ($wildcards == 'sql') { - } elseif ($wildcards == 'none') { - $text = str_replace(array('%', '_'), array('\\%', '\\_'), $text); - } - return $text; - } - - /** - * Initial app setup code. - */ - function initialize() - { - /* Store the request timestamp if it's not already present. */ - if (!isset($_SERVER['REQUEST_TIME'])) { - $_SERVER['REQUEST_TIME'] = time(); - } - - // Update the preference for what ledgers to display. If the user - // doesn't have any selected ledger for view then fall back to - // some available ledger. - $GLOBALS['display_ledgers'] = @unserialize($GLOBALS['prefs']->getValue('display_ledgers')); - if (!$GLOBALS['display_ledgers']) { - $GLOBALS['display_ledgers'] = array(); - } - if (($ledgerId = Horde_Util::getFormData('display_ledger')) !== null) { - if (is_array($ledgerId)) { - $GLOBALS['display_ledgers'] = $ledgerId; - } else { - if (in_array($ledgerId, $GLOBALS['display_ledgers'])) { - $key = array_search($ledgerId, $GLOBALS['display_ledgers']); - unset($GLOBALS['display_ledgers'][$key]); - } else { - $GLOBALS['display_ledgers'][] = $ledgerId; - } - } - } - - // Make sure all ledgers exist now, to save on checking later. - $_temp = $GLOBALS['display_ledgers']; - $GLOBALS['all_ledgers'] = Fima::listLedgers(); - $GLOBALS['display_ledgers'] = array(); - foreach ($_temp as $id) { - if (isset($GLOBALS['all_ledgers'][$id])) { - $GLOBALS['display_ledgers'][] = $id; - } - } - - if (count($GLOBALS['display_ledgers']) == 0) { - $ledgerss = Fima::listLedgers(true); - if (!$GLOBALS['registry']->getAuth()) { - /* All ledgers for guests. */ - $GLOBALS['display_ledgers'] = array_keys($ledgers); - } else { - /* Make sure at least the active ledger is visible. */ - $active_ledger = Fima::getActiveLedger(Horde_Perms::READ); - if ($active_ledger) { - $GLOBALS['display_ledgers'] = array($active_ledger); - } - - /* If the user's personal ledger doesn't exist, then create it. */ - if (!$GLOBALS['fima_shares']->exists($GLOBALS['registry']->getAuth())) { - $identity = $GLOBALS['injector']->getInstance('Horde_Prefs_Identity')->getIdentity(); - $name = $identity->getValue('fullname'); - if (trim($name) == '') { - $name = $GLOBALS['registry']->getAuth('original'); - } - $share = &$GLOBALS['fima_shares']->newShare($GLOBALS['registry']->getAuth()); - $share->set('name', sprintf(_("%s's Ledger"), $name)); - $GLOBALS['fima_shares']->addShare($share); - - /* Make sure the personal ledger is displayed by default. */ - if (!in_array($GLOBALS['registry']->getAuth(), $GLOBALS['display_ledgers'])) { - $GLOBALS['display_ledgers'][] = $GLOBALS['registry']->getAuth(); - } - } - } - } - - $GLOBALS['prefs']->setValue('display_ledgers', serialize($GLOBALS['display_ledgers'])); - - /* Update active ledger. */ - if (($changeledger = Horde_Util::getFormData('changeledger')) !== null) { - $GLOBALS['prefs']->setValue('active_ledger', $changeledger); - } - } - - /** - * Build Fima's list of menu items. - */ - function getMenu() - { - global $conf, $browser, $print_link; - - $actionID = Horde_Util::getFormData('actionID'); - $hordeimg = Horde_Themes::img(null, 'horde'); - - $menu = new Horde_Menu(Horde_Menu::MASK_ALL); - $menu->add(Horde::url('postings.php'), _("_List Postings"), 'list.png', null, null, null, (basename($_SERVER['PHP_SELF']) == 'index.php' && basename(dirname($_SERVER['PHP_SELF'])) != 'ledgers') ? 'current' : ($actionID === null ? null : '__noselection')); - $menu->add(Horde_Util::addParameter(Horde::url('postings.php'), 'actionID', 'add_postings'), _("Add _Postings"), 'add.png', null, null, null, $actionID == 'add_postings' ? 'current' : '__noselection'); - $menu->add(Horde::url('search.php'), _("Search"), 'search.png', $hordeimg); - $menu->add(Horde::url('accounts.php'), _("_Accounts"), 'accounts.png'); - - if ($GLOBALS['registry']->getAuth()) { - $menu->add(Horde::url('ledgers/index.php'), _("_My Ledgers"), 'accounts.png'); - } - - /* Reports. */ - $menu->add(Horde::url('report.php'), _("_Reports"), 'report.png'); - - /* Import/Export. */ - $menu->add(Horde::url('data.php'), _("_Import/Export"), 'data.png', $hordeimg); - - /* Print. */ - if (isset($print_link)) { - $menu->add($print_link, _("_Print"), 'print.png', $hordeimg, '_blank', Horde::popupJs($print_link, array('urlencode' => true)) . 'return false;', '__noselection'); - } - - return $menu; - } - -} diff --git a/fima/lib/Forms/CreateLedger.php b/fima/lib/Forms/CreateLedger.php deleted file mode 100644 index ad50492a7..000000000 --- a/fima/lib/Forms/CreateLedger.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @package Fima - */ -class Fima_CreateLedgerForm extends Horde_Form { - - function Fima_CreateLedgerForm(&$vars) - { - parent::Horde_Form($vars, _("Create Ledger")); - - $this->addVariable(_("Name"), 'name', 'text', true); - $this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60)); - - $this->setButtons(array(_("Create"))); - } - - function execute() - { - // Create new share. - $ledger = $GLOBALS['fima_shares']->newShare(strval(new Horde_Support_Uuid())); - if (is_a($ledger, 'PEAR_Error')) { - return $ledger; - } - $ledger->set('name', $this->_vars->get('name')); - $ledger->set('desc', $this->_vars->get('description')); - return $GLOBALS['fima_shares']->addShare($ledger); - } - -} diff --git a/fima/lib/Forms/DeleteLedger.php b/fima/lib/Forms/DeleteLedger.php deleted file mode 100644 index 0969d6e35..000000000 --- a/fima/lib/Forms/DeleteLedger.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @package Fima - */ -class Fima_DeleteLedgerForm extends Horde_Form { - - /** - * Ledger being deleted - */ - var $_ledger; - - function Fima_DeleteLedgerForm(&$vars, &$ledger) - { - $this->_ledger = &$ledger; - parent::Horde_Form($vars, sprintf(_("Delete %s"), $ledger->get('name'))); - - $this->addHidden('', 'l', 'text', true); - $this->addVariable(sprintf(_("Really delete the ledger \"%s\"? This cannot be undone and all data on this ledger will be permanently removed."), $this->_ledger->get('name')), 'desc', 'description', false); - - $this->setButtons(array(_("Delete"), _("Cancel"))); - } - - function execute() - { - // If cancel was clicked, return false. - if ($this->_vars->get('submitbutton') == _("Cancel")) { - return false; - } - - if ($this->_ledger->get('owner') != $GLOBALS['registry']->getAuth()) { - return PEAR::raiseError(_("Permission denied")); - } - - // Delete the ledger. - $storage = &Fima_Driver::singleton($this->_ledger->getName()); - $result = $storage->deleteAll(); - if (is_a($result, 'PEAR_Error')) { - return PEAR::raiseError(sprintf(_("Unable to delete \"%s\": %s"), $this->_ledger->get('name'), $result->getMessage())); - } else { - // Remove share and all groups/permissions. - $result = $GLOBALS['fima_shares']->removeShare($this->_ledger); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - } - - // Make sure we still own at least one ledger. - if (count(Fima::listLedgers(true)) == 0) { - // If the default share doesn't exist then create it. - if (!$GLOBALS['fima_shares']->exists($GLOBALS['registry']->getAuth())) { - $identity = $GLOBALS['injector']->getInstance('Horde_Prefs_Identity')->getIdentity(); - $name = $identity->getValue('fullname'); - if (trim($name) == '') { - $name = $GLOBALS['registry']->getAuth('original'); - } - $ledger = &$GLOBALS['fima_shares']->newShare($GLOBALS['registry']->getAuth()); - if (is_a($ledger, 'PEAR_Error')) { - return; - } - $ledger->set('name', sprintf(_("%s's Ledger"), $name)); - $GLOBALS['fima_shares']->addShare($ledger); - } - } - - return true; - } - -} diff --git a/fima/lib/Forms/EditLedger.php b/fima/lib/Forms/EditLedger.php deleted file mode 100644 index 04d8bfb1a..000000000 --- a/fima/lib/Forms/EditLedger.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package Fima - */ -class Fima_EditLedgerForm extends Horde_Form { - - /** - * Ledger being edited - */ - var $_ledger; - - function Fima_EditLedgerForm(&$vars, &$ledger) - { - $this->_ledger = &$ledger; - parent::Horde_Form($vars, sprintf(_("Edit %s"), $ledger->get('name'))); - - $this->addHidden('', 'l', 'text', true); - $this->addVariable(_("Name"), 'name', 'text', true); - $this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60)); - - $this->setButtons(array(_("Save"))); - } - - function execute() - { - $this->_ledger->set('name', $this->_vars->get('name')); - $this->_ledger->set('desc', $this->_vars->get('description')); - $result = $this->_ledger->save(); - if (is_a($result, 'PEAR_Error')) { - return PEAR::raiseError(sprintf(_("Unable to save ledger \"%s\": %s"), $id, $result->getMessage())); - } - return true; - } - -} diff --git a/fima/lib/Forms/account.php b/fima/lib/Forms/account.php deleted file mode 100644 index e1663cddb..000000000 --- a/fima/lib/Forms/account.php +++ /dev/null @@ -1,183 +0,0 @@ - - * @package Fima - */ -class Fima_AccountForm extends Horde_Form { - - function Fima_AccountForm(&$vars, $title = '', $delete = false) - { - parent::Horde_Form($vars, $title); - - $this->addHidden('', 'actionID', 'text', true); - $this->addHidden('', 'account_id', 'text', false); - $this->addHidden('', 'number', 'text', false); - $this->addHidden('', 'parent_id', 'text', false); - - $this->addVariable(_("Number"), 'number_new', 'text', true, false, false, array('/\d{1,4}/', 4, 4)); - $this->addVariable(_("Type"), 'type', 'enum', true, false, false, array(Fima::getAccountTypes())); - $this->addVariable(_("Name"), 'name', 'text', true); - $this->addVariable(_("e.o."), 'eo', 'boolean', false); - $this->addVariable(_("Description"), 'desc', 'longtext', false); - $this->addVariable(_("Closed"), 'closed', 'boolean', false); - - $buttons = array(_("Save"), _("Save and New")); - if ($delete) { - $buttons[] = _("Delete this account"); - } - $this->setButtons($buttons); - } - - function renderActive() - { - return parent::renderActive(new Fima_AccountForm_Renderer(array('varrenderer_driver' => array('fima', 'fima')), $this->_submit, 2), $this->_vars, 'account.php', 'post'); - } - -} - -/** - * The Fima_AccountDeleteForm class provides the form for deleting an account. - * - * @author Thomas Trethan - * @package Fima - */ -class Fima_AccountDeleteForm extends Horde_Form { - - function Fima_AccountDeleteForm(&$vars, $title = '', $edit = false) - { - parent::Horde_Form($vars, $title); - - $this->addHidden('', 'actionID', 'text', true); - $this->addHidden('', 'account_id', 'text', false); - $this->addHidden('', 'number', 'text', false); - $this->addHidden('', 'name', 'text', false); - $this->addHidden('', 'type', 'text', false); - - $this->addVariable(_("Postings"), 'dspostings', 'fima_dspostings', false); - $this->addVariable(_("Subaccounts"), 'dssubaccounts', 'fima_dssubaccounts', false); - - $buttons = array(_("Delete")); - if ($edit) { - $buttons[] = _("Edit this account"); - } - $this->setButtons($buttons); - } - - function renderActive() - { - return parent::renderActive(new Fima_AccountForm_Renderer(array('varrenderer_driver' => array('fima', 'fima')), $this->_submit, 1), $this->_vars, 'account.php', 'post'); - } - -} -class Fima_AccountForm_Renderer extends Horde_Form_Renderer { - - var $buttons; - var $buttonspacer; - - function Fima_AccountForm_Renderer($params = array(), $buttons = array(), $buttonspacer = 1) - { - parent::Horde_Form_Renderer($params); - $this->buttons = $buttons; - $this->buttonspacer = $buttonspacer; - } - - function _renderSubmit($submit, $reset) - { -?>
-buttons as $key => $button): ?> - - -
-
- - * @package Fima - */ -class Horde_Form_Type_fima_dspostings extends Horde_Form_Type { - - function getInfo(&$vars, &$var, &$info) - { - $ds = $var->getValue($vars); - if ($ds['type'] == 'delete') { - $info = true; - } elseif ($ds['type'] == 'shift') { - $info = $ds['account']; - } else { - $info = false; - } - } - - function isValid(&$var, &$vars, $value, &$message) - { - if ($value['type'] == 'shift' && $value['account'] == $vars->get('account_id')) { - $message = _("Select another account where to shift postings to."); - return false; - } - - return true; - } - -} - -/** - * The Horde_Form_Type_fima_dssubaccounts class provides a form field for selecting - * the handling (delete/shift) of subaccounts when deleting an account. - * - * @author Thomas Trethan - * @package Fima - */ -class Horde_Form_Type_fima_dssubaccounts extends Horde_Form_Type { - - function getInfo(&$vars, &$var, &$info) - { - $ds = $var->getValue($vars); - if ($ds['type'] == 'none') { - $info = false; - } elseif ($ds['type'] == 'delete') { - $info = true; - } elseif ($ds['type'] == 'shift') { - $info = $ds['account']; - } else { - $info = false; - } - } - - function isValid(&$var, &$vars, $value, &$message) - { - if ($value['type'] == 'shift' && $value['account'] == $vars->get('account_id')) { - $message = _("Select another account where to shift subaccount postings to."); - return false; - } - - return true; - } - -} diff --git a/fima/lib/Report.php b/fima/lib/Report.php deleted file mode 100644 index eb60d5f38..000000000 --- a/fima/lib/Report.php +++ /dev/null @@ -1,186 +0,0 @@ - - * @package Fima - */ -class Fima_Report { - - /** - * Hash containing report parameters. - * - * @var array - */ - var $_params = array(); - - /** - * Array containing the data after execution of the report. - * - * @var mixed - */ - var $_data = array(); - - /** - * Bytes containing the report graph after execution of the report. - * - * @var bytes - */ - var $_graph = null; - - /** - * Constructor - just store the $params in our newly-created - * object. All other work is done by initialize(). - * - * @param array $params Any parameters needed for this driver. - */ - function Fima_Report($params = array(), $errormsg = null) - { - $this->_params = $params; - if (is_null($errormsg)) { - $this->_errormsg = _("The Finances reports are not currently available."); - } else { - $this->_errormsg = $errormsg; - } - } - - /** - * Returns a specific report parameter. - * - * @param string $param Paramter to retrieve. - * - * @return mixed Report parameter - */ - function getParam($param) - { - if (isset($this->_params[$param])) { - return $this->_params[$param]; - } else { - return null; - } - } - - /** - * Set a specific report parameter. - * - * @param string $param Paramter to set. - * @param mixed $vale Value to set paramter to. - * - * @return mixed Report parameter on success, else null - */ - function setParam($param, $value) - { - $this->_params[$param] = $value; - return $value; - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function execute() - { - $execute = $this->_execute(); - if (is_a($execute, 'PEAR_Error')) { - return $execute; - } - - /* Log the execution of the report in the history log. */ - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:report:' . $this->_params['report_id'], array('action' => 'execute'), true); - - return true; - } - - /** - * Returns the data after report is executed. - * - * @return array Data matrix - */ - function getData() - { - return $this->_data; - } - - /** - * Output the graph of this report. - * - * @return mixed True or PEAR Error - */ - function getGraph() - { - $execute = $this->_getGraph(); - if (is_a($execute, 'PEAR_Error')) { - return $execute; - } - - require_once FIMA_BASE . '/lib/ReportGraph.php'; - $graph = &Fima_ReportGraph::factory($this->_params['graph'], $this->data, $this->_params); - if (is_a($graph, 'PEAR_Error')) { - $notification->push(sprintf(_("There was a problem creating the report graph: %s."), $report->getMessage()), 'horde.error'); - return $graph; - } - - /* Execute report graph. */ - $graph->execute(); - if (is_a($status, 'PEAR_Error')) { - $notification->push(sprintf(_("There was a problem executing the report graph: %s."), $status->getMessage()), 'horde.error'); - return $status; - } - - $graph->getGraph(); - return true; - } - - /** - * Initialization of the report. - * - * @return boolean True on success; PEAR_Error on failure. - */ - function initialize() - { - } - - /** - * Attempts to return a concrete Fima_Report instance based on $driver. - * - * @param string $driver The type of the concrete Fima_Report subclass - * to return. The class name is based on the - * storage driver ($driver). The code is - * dynamically included. - * - * @param array $params (optional) A hash containing any additional - * configuration or connection parameters a - * subclass might need. - * - * @return mixed The newly created concrete Fima_Driver instance, or - * false on an error. - */ - function &factory($driver = null, $params = null) - { - if ($driver === null) { - $report = new Fima_Report($params, _("No report driver loaded")); - return $report; - } - - require_once dirname(__FILE__) . '/Report/' . $driver . '.php'; - $class = 'Fima_Report_' . $driver; - if (class_exists($class)) { - $report = new $class($params); - $result = $report->initialize(); - if (is_a($result, 'PEAR_Error')) { - $report = new Fima_Report($params, sprintf(_("The Finances reports are not currently available: %s"), $result->getMessage())); - } - } else { - $report = new Fima_Report($params, sprintf(_("Unable to load the definition of %s."), $class)); - } - - return $report; - } - -} diff --git a/fima/lib/Report/AccountOverview.php b/fima/lib/Report/AccountOverview.php deleted file mode 100644 index ffac9d8d4..000000000 --- a/fima/lib/Report/AccountOverview.php +++ /dev/null @@ -1,286 +0,0 @@ - - * @package Fima - */ -class Fima_Report_AccountOverview extends Fima_Report { - - /* - * Constructs a new AccountOverview Report. - */ - function Fima_Report_AccountOverview($params = array()) - { - $this->_params = $params; - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Get posting types. */ - $postingtypes = Fima::getPostingTypes(); - - /* Params. */ - if (($display = $this->getParam('display')) === null) { - return PEAR::raiseError(_("No display type")); - } - $posting_account = $this->getParam('posting_account'); - $period_start = $this->getParam('period_start'); - $period_end = $this->getParam('period_end'); - $reference_start = $this->getParam('reference_start'); - $reference_end = $this->getParam('reference_end'); - $cumulate = $this->getParam('cumulate'); - $nullrows = $this->getParam('nullrows'); - $yearly = $this->getParam('yearly'); - $graph = $this->getParam('graph'); - $datefmt = $yearly ? '%Y' : Fima::convertDateToPeriodFormat($GLOBALS['prefs']->getValue('date_format')); - $sortby = $this->getParam('sortby'); - $sortdir = $this->getParam('sortdir'); - - /* Rows. */ - $rows = array(); - for ($period = $period_start; $period <= $period_end; $period = strtotime($yearly ? '+1 year' : '+1 month', $period)) { - $rows[strftime($yearly ? '%Y' : '%Y%m', $period)] = strftime($datefmt, $period); - } - - /* Columns. */ - $cols = explode('_', $display); - - $displaypostingtypes = array(); - $displayreference = false; - $displaydiffa = false; - $displaydiffp = false; - - $colheaders = array('__header__' => _("Period")); - $coldummy = array(); - foreach ($cols as $colPos => $colId) { - if (isset($postingtypes[$colId])) { - $displaypostingtypes[] = $colId; - $colheaders[$colId] = $postingtypes[$colId]; - } elseif ($colId == 'reference') { - $displayreference = true; - $colheaders[$colId] = _("Reference"); - } elseif ($colId == 'difference') { - $displaydiffa = $colPos; - $colheaders[$colId] = _("Difference"); - } elseif ($colId == '%') { - $displaydiffp = $colPos; - $colheaders[$colId] = _("Diff. (%)"); - } - $coldummy[$colId] = 0; - } - - - /* Initialize matrix. */ - $data = array(); - $data['__headersort__'] = $colheaders; - foreach ($rows as $rowId => $rowLabel) { - $data[$rowId] = array('__header__' => $rowLabel) + $coldummy; - } - - /* Results. */ - $total = array('__header__' => _("Total Result")) + $coldummy; - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', FIMA_ACCOUNTTYPE_ASSET, '<>'); - $filters[] = array('type', $cols); - if ($period_start !== null) { - $filters[] = array('date', (int)$period_start, '>='); - } - if ($period_end !== null) { - $filters[] = array('date', (int)$period_end, '<='); - } - $result = Fima::getResults(array('type', $yearly ? 'date_year' : 'date_month'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $data[$rowId][$colId] = $value; - $total[$colId] += $value; - } - } - $data['__result__'] = $total; - - /* Reference. */ - if ($displayreference) { - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', $rows); - $filters[] = array('type', $displaypostingtypes[0]); - if ($reference_start !== null) { - $filters[] = array('date', (int)$reference_start, '>='); - } - if ($reference_end !== null) { - $filters[] = array('date', (int)$reference_end, '<='); - } - - $result = Fima::getResults(array('type', $yearly ? 'date_year' : 'date_month'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $colId = 'reference'; - $data[$rowId][$colId] = $value; - $data['__result__'][$colId] += $value; - } - } - } - - /* Difference. */ - if ($displaydiffa > 1 || $displaydiffp > 1) { - $cola1 = $cols[$displaydiffa - 2]; - $cola2 = $cols[$displaydiffa - 1]; - $colp1 = $cols[$displaydiffp - 2]; - $colp2 = $cols[$displaydiffp - 1]; - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - continue; - } - if ($displaydiffa > 1) { - $data[$rowId]['difference'] = $data[$rowId][$cola1] - $data[$rowId][$cola2]; - } - if ($displaydiffp > 1) { - if ($data[$rowId][$colp1] != 0) { - $data[$rowId]['%'] = $data[$rowId][$colp2] / abs($data[$rowId][$colp1]) * 100; - } else { - $data[$rowId]['%'] = null; - } - } - } - } - - /* Null Rows and Cumulate. */ - if (!$nullrows || $cumulate) { - $cumulatevalue = $coldummy; - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - continue; - } - $isnullrow = true; - foreach ($row as $colId => $value) { - if (preg_match('/__(header).*__/', $colId) || $colId == '__resultasset__') { - continue; - } - if ($cumulate) { - $data[$rowId][$colId] += $cumulatevalue[$colId]; - $cumulatevalue[$colId] = $data[$rowId][$colId]; - } - if ($data[$rowId][$colId] != 0) { - $isnullrow = false; - } - } - if (!$nullrows && $isnullrow) { - unset($data[$rowId]); - } - } - } - - /* Sorting. */ - if ($sortby === null || !isset($colheaders[$sortby])) { - $sortby = $this->setParam('sortby', '__header__'); - } - if ($sortdir === null) { - $sortdir = $this->setParam('sortdir', FIMA_SORT_ASCEND); - } - if ($graph) { - $sortby = '__header__'; - $sortdir = FIMA_SORT_ASCEND; - } - - $x = -1; - $sortIndex = array(); - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - $x++; - $sortIndex[$x] = array($rowId => $row[$sortby]); - $x++; - } else { - if (!isset($sortIndex[$x])) { - $sortIndex[$x] = array(); - } - $sortIndex[$x][$rowId] = $row[$sortby]; - } - } - - foreach ($sortIndex as $indexId => $indexGroup) { - if (count($indexGroup) > 0) { - if ($sortdir) { - arsort($indexGroup); - } else { - asort($indexGroup); - } - } - foreach ($indexGroup as $rowId => $index) { - $this->_data[$rowId] = $data[$rowId]; - } - } - - return true; - } - - /* - * Output the graph. - * - * @return mixed True or PEAR Error - */ - function _getGraph() - { - /* Data. */ - $display = explode('_', $this->getParam('display')); - $display = ($display[0] == 'reference') ? $display[1] : $display[0]; - $postingtypes = Fima::getPostingTypes(); - - $labels = array(); - $data = $this->_data; - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - foreach ($row as $colId => $value) { - if (!(preg_match('/__(header|result).*__/', $colId) && $colId != '__resulttotal__')) { - $labels[$colId] = $value; - } - } - } - if (preg_match('/__(header|result).*__/', $rowId)) { - unset($data[$rowId]); - } else { - $labels[$rowId] = isset($row['__header__']) ? $row['__header__'] : $rowId; - foreach ($row as $colId => $value) { - if (preg_match('/__(header|result).*__/', $colId) && $colId != '__resulttotal__') { - unset($data[$rowId][$colId]); - } - } - } - } - $this->data = $data; - - /* Additional params. */ - $this->setParam('graph', 'Line'); - $this->setParam('labels', $labels); - - return true; - } - -} diff --git a/fima/lib/Report/Analysis.php b/fima/lib/Report/Analysis.php deleted file mode 100644 index 0dce0869a..000000000 --- a/fima/lib/Report/Analysis.php +++ /dev/null @@ -1,384 +0,0 @@ - - * @package Fima - */ -class Fima_Report_Analysis extends Fima_Report { - - /* - * Constructs a new Analysis Report. - */ - function Fima_Report_Analysis($params = array()) - { - $this->_params = $params; - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Get account types, posting types and accounts. */ - $accounttypes = Fima::getAccountTypes(); - $postingtypes = Fima::getPostingTypes(); - $accounts = Fima::listAccounts(); - $accountIndex = array(); - foreach ($accounts as $accountId => $account) { - $accountIndex[$account['number']] = $accountId; - } - $groups = array(FIMA_ACCOUNTTYPE_INCOME, FIMA_ACCOUNTTYPE_EXPENSE); - - /* Params. */ - if (($display = $this->getParam('display')) === null) { - return PEAR::raiseError(_("No display type")); - } - $posting_account = $this->getParam('posting_account'); - $period_start = $this->getParam('period_start'); - $period_end = $this->getParam('period_end'); - $reference_start = $this->getParam('reference_start'); - $reference_end = $this->getParam('reference_end'); - $subaccounts = $this->getParam('subaccounts'); - $nullrows = $this->getParam('nullrows'); - $graph = $this->getParam('graph'); - $sortby = $this->getParam('sortby'); - $sortdir = $this->getParam('sortdir'); - - /* Rows. */ - // accounts (dynamically) - - /* Columns. */ - $cols = explode('_', $display); - - $displaypostingtypes = array(); - $displayreference = false; - $displaydiffa = false; - $displaydiffp = false; - - $colheaders = array('__header__' => _("Account")); - $coldummy = array(); - foreach ($cols as $colPos => $colId) { - if (isset($postingtypes[$colId])) { - $displaypostingtypes[] = $colId; - $colheaders[$colId] = $postingtypes[$colId]; - } elseif ($colId == 'reference') { - $displayreference = true; - $colheaders[$colId] = _("Reference"); - } elseif ($colId == 'difference') { - $displaydiffa = $colPos; - $colheaders[$colId] = _("Difference"); - } elseif ($colId == '%') { - $displaydiffp = $colPos; - $colheaders[$colId] = _("Diff. (%)"); - } - $coldummy[$colId] = 0; - } - - /* Initialize matrix. */ - $data = array(); - $data['__headersort__'] = $colheaders; - $datagroups = array(FIMA_ACCOUNTTYPE_INCOME => array(), FIMA_ACCOUNTTYPE_EXPENSE => array()); - // add parent accounts - if ($posting_account) { - foreach ($posting_account as $accountId => $account) { - if ($accounts[$account]['parent_id']) { - $posting_account[] = $accounts[$account]['parent_id']; - } - } - } - foreach ($accounts as $accountId => $account) { - if ($posting_account) { - if (!in_array($account['account_id'], $posting_account)) { - continue; - } - } - if ($account['type'] == FIMA_ACCOUNTTYPE_ASSET) { - continue; - } - if ($account['parent_id'] === null || !isset($accounts[$account['parent_id']])) { - $datagroups[$account['type']][$account['number']] = array('__header__' => $account['label']) + $coldummy; - if ($subaccounts) { - $datagroups[$account['type']][$account['number']]['__subaccounts__'] = array(); - } - } elseif ($subaccounts) { - $datagroups[$account['type']][$accounts[$account['parent_id']]['number']]['__subaccounts__'][$account['number']] = array('__header__' => ' '.$account['label']) + $coldummy; - } - } - foreach ($datagroups as $datagroupId => $datagroup) { - $datagroups[$datagroupId]['__result' . $datagroupId . '__'] = array('__header__' => sprintf(_("%s Result"), $accounttypes[$datagroupId])) + $coldummy; - $data += $datagroups[$datagroupId]; - } - - /* Results. */ - foreach ($groups as $group) { - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', $group); - $filters[] = array('type', $displaypostingtypes); - if ($period_start !== null) { - $filters[] = array('date', (int)$period_start, '>='); - } - if ($period_end !== null) { - $filters[] = array('date', (int)$period_end, '<='); - } - - $result = Fima::getResults(array('type', $subaccounts ? 'account_number' : 'account_parent'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - if (isset($data[$rowId])) { - $data[$rowId][$colId] += $value; - } elseif (($parentId = $accounts[$accountIndex[$rowId]]['parent_id']) !== null) { - if (!$graph) { - $data[$accounts[$parentId]['number']][$colId] += $value; - } - $data[$accounts[$parentId]['number']]['__subaccounts__'][$rowId][$colId] += $value; - } - $data['__result' . $group . '__'][$colId] += $value; - } - } - } - - /* Reference. */ - if ($displayreference) { - foreach ($groups as $group) { - $groupresult = array(); - - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', $group); - $filters[] = array('type', $displaypostingtypes); - if (($reference_start = $this->getParam('reference_start')) !== null) { - $filters[] = array('date', (int)$reference_start, '>='); - } - if (($reference_end = $this->getParam('reference_end')) !== null) { - $filters[] = array('date', (int)$reference_end, '<='); - } - - $result = Fima::getResults(array('type', $subaccounts ? 'account_number' : 'account_parent'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $colId = 'reference'; - if (isset($data[$rowId])) { - $data[$rowId][$colId] += $value; - } elseif (($parentId = $accounts[$accountIndex[$rowId]]['parent_id']) !== null) { - $data[$accounts[$parentId]['number']][$colId] += $value; - $data[$accounts[$parentId]['number']]['__subaccounts__'][$rowId][$colId] += $value; - } - $data['__result' . $group . '__'][$colId] += $value; - } - } - } - } - - /* Totals. */ - $data['__resulttotal__'] = array('__header__' => _("Total Result")) + $coldummy; - foreach ($cols as $colId) { - foreach ($groups as $groupId => $group) { - $data['__resulttotal__'][$colId] += $data['__result' . $group . '__'][$colId]; - } - } - - /* Difference. */ - if ($displaydiffa > 1 || $displaydiffp > 1) { - $cola1 = $cols[$displaydiffa - 2]; - $cola2 = $cols[$displaydiffa - 1]; - $colp1 = $cols[$displaydiffp - 2]; - $colp2 = $cols[$displaydiffp - 1]; - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - continue; - } - if ($displaydiffa > 1) { - $data[$rowId]['difference'] = $data[$rowId][$cola1] - $data[$rowId][$cola2]; - } - if ($displaydiffp > 1) { - if ($data[$rowId][$colp1] != 0) { - $data[$rowId]['%'] = $data[$rowId][$colp2] / abs($data[$rowId][$colp1]) * 100; - } else { - $data[$rowId]['%'] = null; - } - } - } - } - - /* Null Rows. */ - if (!$nullrows) { - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - continue; - } - $isnullrow = true; - foreach ($row as $colId => $value) { - if (preg_match('/__(header).*__/', $colId) || $colId == '__resultasset__') { - continue; - } - if ($value != 0) { - $isnullrow = false; - } - } - if (!$nullrows && $isnullrow) { - unset($data[$rowId]); - } - } - } - - /* Sorting. */ - if ($sortby === null || !isset($colheaders[$sortby])) { - $sortby = $this->setParam('sortby', '__header__'); - } - if ($sortdir === null) { - $sortdir = $this->setParam('sortdir', FIMA_SORT_ASCEND); - } - $x = -1; - $sortIndex = array(); - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - $x++; - $sortIndex[$x] = array($rowId => $row[$sortby]); - $x++; - } else { - if (!isset($sortIndex[$x])) { - $sortIndex[$x] = array(); - } - $sortIndex[$x][$rowId] = $row[$sortby]; - } - } - - foreach ($sortIndex as $indexId => $indexGroup) { - if (count($indexGroup) > 0) { - if ($sortdir) { - arsort($indexGroup); - } else { - asort($indexGroup); - } - } - foreach ($indexGroup as $rowId => $index) { - $this->_data[$rowId] = $data[$rowId]; - if (isset($data[$rowId]['__subaccounts__'])) { - if (count($data[$rowId]['__subaccounts__']) > 0) { - $subSortIndex = array(); - foreach ($data[$rowId]['__subaccounts__'] as $subId => $sub) { - $subSortIndex[$subId] = $sub[$sortby]; - } - if ($sortdir) { - arsort($subSortIndex); - } else { - asort($subSortIndex); - } - - foreach ($subSortIndex as $subId => $sub) { - $this->_data[$subId] = $data[$rowId]['__subaccounts__'][$subId]; - } - } - } - unset($this->_data[$rowId]['__subaccounts__']); - } - } - - return true; - } - - /* - * Output the graph. - * - * @return mixed True or PEAR Error - */ - function _getGraph() - { - /* Data. */ - $display = explode('_', $this->getParam('display')); - - $labels = array(); - $data = array(); - $ix = 0; - foreach ($this->_data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - foreach ($row as $colId => $value) { - $labels[$colId] = $value; - } - } elseif (preg_match('/__(result).*__/', $rowId)) { - $ix++; - } else { - $labels[$rowId] = isset($row['__header__']) ? $row['__header__'] : $rowId; - if (!isset($data[$ix])) { - $data[$ix] = array(); - } - $data[$ix][$rowId] = $row[$display[0]]; - } - } - - // grouping - $sum = array(); - #for ($i = 0; $i < count($data); $i++) { - foreach ($data as $i => $d) { - $sum[$i] = array_sum($data[$i]); - if ($sum[$i] >= 0) { - arsort($data[$i]); - } else { - asort($data[$i]); - } - $topdata = array_slice($data[$i], 0, 5, true); - $data[$i]['__rest__'] = 0; - $data[$i]['__blank__'] = ($sum[$i] == 0) ? 0 : $sum[$i] / abs($sum[$i]); - foreach ($data[$i] as $key => $value) { - if ((!isset($topdata[$key]) || $value == 0) && $key != '__rest__' && $key != '__blank__') { - $data[$i]['__rest__'] += $value; - unset($data[$i][$key]); - } - } - if ($data[$i]['__rest__'] == 0) { - unset($data[$i]['__rest__']); - } - $sum[$i] = abs($sum[$i]); - } - $labels['__rest__'] = _("Rest"); - $labels['__blank__'] = _("Difference"); - - // diff - $max = max($sum); - #for ($i = 0; $i < count($sum); $i++) { - foreach ($sum as $i => $s) { - if ($max != $sum[$i]) { - $data[$i]['__blank__'] *= $max - $sum[$i]; - } else { - unset($data[$i]['__blank__']); - } - } - - $this->data = $data; - - /* Additional params. */ - $this->setParam('graph', 'Pie'); - $this->setParam('labels', $labels); - $this->setParam('subtitle', $labels[($display[0] == 'reference') ? $display[1] : $display[0]]); - $this->setParam('marker', true); - - return true; - } - -} diff --git a/fima/lib/Report/AssetOverview.php b/fima/lib/Report/AssetOverview.php deleted file mode 100644 index f730acd94..000000000 --- a/fima/lib/Report/AssetOverview.php +++ /dev/null @@ -1,325 +0,0 @@ - - * @package Fima - */ -class Fima_Report_AssetOverview extends Fima_Report { - - /* - * Constructs a new AssetOverview Report. - */ - function Fima_Report_AssetOverview($params = array()) - { - $this->_params = $params; - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Get account types, posting types and accounts. */ - $accounts = Fima::listAccounts(array(array('type', FIMA_ACCOUNTTYPE_ASSET))); - $accountIndex = array(); - foreach ($accounts as $accountId => $account) { - $accountIndex[$account['number']] = $accountId; - } - - /* Params. */ - if (($display = $this->getParam('display')) === null) { - return PEAR::raiseError(_("No display type")); - } - $display = explode('_', $display); - $period_start = ($display[0] == 'reference') ? $this->getParam('reference_start') : $this->getParam('period_start'); - $period_end = ($display[0] == 'reference') ? $this->getParam('reference_end') : $this->getParam('period_end'); - $display = ($display[0] == 'reference') ? $display[1] : $display[0]; - $cumulate = $this->getParam('cumulate'); - $nullrows = $this->getParam('nullrows'); - $subaccounts = $this->getParam('subaccounts'); - $graph = $this->getParam('graph'); - $yearly = $this->getParam('yearly'); - $datefmt = $yearly ? '%Y' : Fima::convertDateToPeriodFormat($GLOBALS['prefs']->getValue('date_format')); - $sortby = $this->getParam('sortby'); - $sortdir = $this->getParam('sortdir'); - - /* Rows. */ - // accounts (dynamically) - - /* Columns. */ - $cols = array(); - $colheaders = array('__header__' => _("Asset")); - $coldummy = array(); - for ($period = $period_start; $period <= $period_end; $period = strtotime($yearly ? '+1 year' : '+1 month', $period)) { - $colId = strftime($yearly ? '%Y' : '%Y%m', $period); - $cols[] = $colId; - $colheaders[$colId] = strftime($datefmt, $period); - $coldummy[$colId] = 0; - } - $colheaders['__result__'] = _("Total Result"); - $coldummy['__result__'] = 0; - - /* Initialize matrix. */ - $data = array(); - $data['__headersort__'] = $colheaders; - foreach ($accounts as $accountId => $account) { - if ($account['parent_id'] === null || !isset($accounts[$account['parent_id']])) { - $data[$account['number']] = array('__header__' => $account['label']) + $coldummy; - if ($subaccounts) { - $data[$account['number']]['__subaccounts__'] = array(); - } - } elseif ($subaccounts) { - $data[$accounts[$account['parent_id']]['number']]['__subaccounts__'][$account['number']] = array('__header__' => ' '.$account['label']) + $coldummy; - } - } - $data['__result__'] = array('__header__' => _("Asset Result")) + $coldummy; - - /* Initialize asset results. */ - if ($cumulate) { - $assetresults = Fima::getAssetResults($display, $period_start - 1); - $period = strftime($yearly ? '%Y' : '%Y%m', $period_start); - foreach ($assetresults as $assetresult) { - if (isset($data[$accounts[$assetresult['account_id']]['number']])) { - $data[$accounts[$assetresult['account_id']]['number']][$period] += $assetresult['account_result']; - $data[$accounts[$assetresult['account_id']]['number']]['__result__'] += $assetresult['account_result']; - } elseif (($parentId = $accounts[$assetresult['account_id']]['parent_id']) !== null) { - $data[$accounts[$parentId]['number']][$period] += $assetresult['account_result']; - $data[$accounts[$parentId]['number']]['__result__'] += $assetresult['account_result']; - if ($subaccounts) { - $data[$accounts[$parentId]['number']]['__subaccounts__'][$accounts[$assetresult['account_id']]['number']][$period] += $assetresult['account_result']; - $data[$accounts[$parentId]['number']]['__subaccounts__'][$accounts[$assetresult['account_id']]['number']]['__result__'] += $assetresult['account_result']; - } - } - $data['__result__'][$period] += $assetresult['account_result']; - $data['__result__']['__result__'] += $assetresult['account_result']; - } - } - - /* Results. */ - $filters = array(); - $filters[] = array('type', $display); - if ($period_start !== null) { - $filters[] = array('date', (int)$period_start, '>='); - } - if ($period_end !== null) { - $filters[] = array('date', (int)$period_end, '<='); - } - - // asset accounts - $result = Fima::getResults(array($yearly ? 'date_year' : 'date_month', $subaccounts ? 'asset_number' : 'asset_parent'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - // asset accounts as posting account - $filters[] = array('account_type', FIMA_ACCOUNTTYPE_ASSET); - $result2 = Fima::getResults(array($yearly ? 'date_year' : 'date_month', $subaccounts ? 'account_number' : 'account_parent'), $filters); - if (is_a($result2, 'PEAR_Error')) { - return $result2; - } - foreach ($result2 as $rowId => $row) { - if (!isset($result[$rowId])) { - $result[$rowId] = array(); - } - foreach ($row as $colId => $value) { - if (!isset($result[$rowId][$colId])) { - $result[$rowId][$colId] = 0; - } - $result[$rowId][$colId] -= $value; - } - } - - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - if (isset($data[$rowId])) { - $data[$rowId][$colId] += $value; - $data[$rowId]['__result__'] += $value; - } elseif (($parentId = $accounts[$accountIndex[$rowId]]['parent_id']) !== null) { - $data[$accounts[$parentId]['number']][$colId] += $value; - $data[$accounts[$parentId]['number']]['__result__'] += $value; - if ($subaccounts) { - $data[$accounts[$parentId]['number']]['__subaccounts__'][$rowId][$colId] += $value; - $data[$accounts[$parentId]['number']]['__subaccounts__'][$rowId]['__result__'] += $value; - } - } - $data['__result__'][$colId] += $value; - $data['__result__']['__result__'] += $value; - } - } - - /* Null Rows and Cumulate. */ - if (!$nullrows || $cumulate) { - foreach ($data as $rowId => $row) { - if (preg_match('/__(header).*__/', $rowId)) { - continue; - } - $cumulatevalue = 0; - $isnullrow = true; - foreach ($row as $colId => $value) { - if (preg_match('/__(header|result).*__/', $colId)) { - continue; - } - if ($colId == '__subaccounts__') { - if (count($value) > 0) { - foreach ($value as $subRowId => $subRow) { - $subcumulatevalue = 0; - $subisnullrow = true; - foreach ($subRow as $subColId => $subValue) { - if (preg_match('/__(header|result).*__/', $subColId)) { - continue; - } - if ($cumulate) { - $data[$rowId]['__subaccounts__'][$subRowId][$subColId] += $subcumulatevalue; - $subcumulatevalue = $data[$rowId]['__subaccounts__'][$subRowId][$subColId]; - } - if ($data[$rowId]['__subaccounts__'][$subRowId][$subColId] != 0) { - $subisnullrow = false; - } - } - if (!$nullrows && $subisnullrow) { - unset($data[$rowId]['__subaccounts__'][$subRowId]); - } - } - } - } else { - if ($cumulate) { - $data[$rowId][$colId] += $cumulatevalue; - $cumulatevalue = $data[$rowId][$colId]; - } - if ($data[$rowId][$colId] != 0) { - $isnullrow = false; - } - } - } - if (!$nullrows && $isnullrow) { - unset($data[$rowId]); - } - } - } - - /* Sorting. */ - if ($sortby === null || !isset($colheaders[$sortby])) { - $sortby = $this->setParam('sortby', '__header__'); - } - if ($sortdir === null) { - $sortdir = $this->setParam('sortdir', FIMA_SORT_ASCEND); - } - $x = -1; - $sortIndex = array(); - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - $x++; - $sortIndex[$x] = array($rowId => $row[$sortby]); - $x++; - } else { - if (!isset($sortIndex[$x])) { - $sortIndex[$x] = array(); - } - $sortIndex[$x][$rowId] = $row[$sortby]; - } - } - - foreach ($sortIndex as $indexId => $indexGroup) { - if (count($indexGroup) > 0) { - if ($sortdir) { - arsort($indexGroup); - } else { - asort($indexGroup); - } - } - foreach ($indexGroup as $rowId => $index) { - $this->_data[$rowId] = $data[$rowId]; - if (isset($data[$rowId]['__subaccounts__'])) { - if (count($data[$rowId]['__subaccounts__']) > 0) { - $subSortIndex = array(); - foreach ($data[$rowId]['__subaccounts__'] as $subId => $sub) { - $subSortIndex[$subId] = $sub[$sortby]; - } - if ($sortdir) { - arsort($subSortIndex); - } else { - asort($subSortIndex); - } - - foreach ($subSortIndex as $subId => $sub) { - $this->_data[$subId] = $data[$rowId]['__subaccounts__'][$subId]; - } - } - } - unset($this->_data[$rowId]['__subaccounts__']); - } - } - - return true; - } - - /* - * Output the graph. - * - * @return mixed True or PEAR Error - */ - function _getGraph() - { - /* Data. */ - $display = explode('_', $this->getParam('display')); - $display = ($display[0] == 'reference') ? $display[1] : $display[0]; - $postingtypes = Fima::getPostingTypes(); - - $labels = array(); - $data = $this->_data; - $sum = array(); - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - foreach ($row as $colId => $value) { - if (!(preg_match('/__(header|result).*__/', $colId) && $colId != '__resulttotal__')) { - $labels[$colId] = $value; - } - } - } - if (preg_match('/__(header|result).*__/', $rowId)) { - unset($data[$rowId]); - } else { - $labels[$rowId] = isset($row['__header__']) ? $row['__header__'] : $rowId; - if ($data[$rowId]['__result__'] != 0) { - $sum[$rowId] = $data[$rowId]['__result__']; - } - unset($data[$rowId]['__header__']); - unset($data[$rowId]['__result__']); - } - } - - // grouping - asort($sum); - $topdata = array_slice($sum, 0, 5, true) + array_slice($sum, -5, 5, true); - foreach ($data as $rowId => $row) { - if (!isset($topdata[$rowId])) { - unset($data[$rowId]); - } - } - - $this->data = $data; - - /* Additional params. */ - $this->setParam('graph', 'Line'); - $this->setParam('labels', $labels); - $this->setParam('subtitle', $postingtypes[$display]); - $this->setParam('invert', true); - - return true; - } - -} diff --git a/fima/lib/Report/GeneralOverview.php b/fima/lib/Report/GeneralOverview.php deleted file mode 100644 index a87f5881e..000000000 --- a/fima/lib/Report/GeneralOverview.php +++ /dev/null @@ -1,266 +0,0 @@ - - * @package Fima - */ -class Fima_Report_GeneralOverview extends Fima_Report { - - /* - * Constructs a new GeneralOverview Report. - */ - function Fima_Report_GeneralOverview($params = array()) - { - $this->_params = $params; - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Get account types and posting types. */ - $accounttypes = Fima::getAccountTypes(); - $postingtypes = Fima::getPostingTypes(); - - /* Params. */ - if (($display = $this->getParam('display')) === null) { - return PEAR::raiseError(_("No display type")); - } - $posting_account = $this->getParam('posting_account'); - $period_start = $this->getParam('period_start'); - $period_end = $this->getParam('period_end'); - $reference_start = $this->getParam('reference_start'); - $reference_end = $this->getParam('reference_end'); - - /* Rows. */ - $rows = array(FIMA_ACCOUNTTYPE_INCOME, FIMA_ACCOUNTTYPE_EXPENSE); - $groups = array('0' => "%s", '1' => "e.o. %s", 'total' => "Total %s"); - $rowheaders = array(); - foreach ($groups as $groupId => $group) { - foreach ($rows as $rowPos => $rowId) { - $rowheaders[$rowId . $groupId] = sprintf(_($group), $accounttypes[$rowId]); - } - $rowheaders['__result' . $groupId . '__'] = sprintf(_($group), _("Result")); - } - $rowheaders['__resultasset__'] = _("Asset Result"); - - /* Columns. */ - $cols = explode('_', $display); - - $displaypostingtypes = array(); - $displayreference = false; - $displaydiffa = false; - $displaydiffp = false; - - $colheaders = array('__header__' => _("Type")); - $coldummy = array(); - foreach ($cols as $colPos => $colId) { - if (isset($postingtypes[$colId])) { - $displaypostingtypes[] = $colId; - $colheaders[$colId] = $postingtypes[$colId]; - } elseif ($colId == 'reference') { - $displayreference = true; - $colheaders[$colId] = _("Reference"); - } elseif ($colId == 'difference') { - $displaydiffa = $colPos; - $colheaders[$colId] = _("Difference"); - } elseif ($colId == '%') { - $displaydiffp = $colPos; - $colheaders[$colId] = _("Diff. (%)"); - } - $coldummy[$colId] = 0; - } - - /* Initialize matrix. */ - $data = array(); - $data['__header__'] = $colheaders; - foreach ($rowheaders as $rowId => $rowheader) { - $data[$rowId] = array('__header__' => $rowheader) + $coldummy;; - } - $assetresult = array('__header__' => _("Asset Result")) + $coldummy; - - /* Results. */ - $groups = array('0', '1'); - foreach ($groups as $group) { - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', $rows); - $filters[] = array('type', $displaypostingtypes); - $filters[] = array('eo', $group); - if ($period_start !== null) { - $filters[] = array('date', (int)$period_start, '>='); - } - if ($period_end !== null) { - $filters[] = array('date', (int)$period_end, '<='); - } - - $result = Fima::getResults(array('type', 'account_type'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $data[$rowId . $group][$colId] = $value; - $data['__result' . $group . '__'][$colId] += $value; - } - } - } - - // asset results - $filters = array(); - $filters[] = array('account_type', FIMA_ACCOUNTTYPE_ASSET, '<>'); - $filters[] = array('type', $displaypostingtypes); - if ($period_end !== null) { - $filters[] = array('date', (int)$period_end, '<'); - } - - $result = Fima::getResults('type', $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $data['__resultasset__'][$colId] = $value; - } - } - - /* Reference. */ - if ($displayreference) { - $groups = array('0', '1'); - foreach ($groups as $group) { - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', $rows); - $filters[] = array('type', $displaypostingtypes[0]); - $filters[] = array('eo', $group); - if ($reference_start !== null) { - $filters[] = array('date', (int)$reference_start, '>='); - } - if ($reference_end !== null) { - $filters[] = array('date', (int)$reference_end, '<='); - } - - $result = Fima::getResults(array('type', 'account_type'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $colId = 'reference'; - $data[$rowId . $group][$colId] = $value; - $data['__result' . $group . '__'][$colId] += $value; - } - } - } - - // asset results - $filters = array(); - $filters[] = array('account_type', FIMA_ACCOUNTTYPE_ASSET, '<>'); - $filters[] = array('type', $displaypostingtypes[0]); - if ($reference_end !== null) { - $filters[] = array('date', (int)$reference_end, '<'); - } - - $result = Fima::getResults('type', $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $data['__resultasset__']['reference'] = $value; - } - } - } - - /* Totals. */ - foreach ($cols as $colId) { - foreach ($rows as $rowId) { - $data[$rowId . 'total'][$colId] = $data[$rowId . '0'][$colId] + $data[$rowId . '1'][$colId]; - } - $data['__resulttotal__'][$colId] = $data['__result0__'][$colId] + $data['__result1__'][$colId]; - } - - /* Difference. */ - if ($displaydiffa > 1 || $displaydiffp > 1) { - $cola1 = $cols[$displaydiffa - 2]; - $cola2 = $cols[$displaydiffa - 1]; - $colp1 = $cols[$displaydiffp - 2]; - $colp2 = $cols[$displaydiffp - 1]; - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - continue; - } - if ($displaydiffa > 1) { - $data[$rowId]['difference'] = $data[$rowId][$cola1] - $data[$rowId][$cola2]; - } - if ($displaydiffp > 1) { - if ($data[$rowId][$colp1] != 0) { - $data[$rowId]['%'] = $data[$rowId][$colp2] / abs($data[$rowId][$colp1]) * 100; - } else { - $data[$rowId]['%'] = null; - } - } - } - } - - $this->_data = $data; - - return true; - } - - /* - * Output the graph. - * - * @return mixed True or PEAR Error - */ - function _getGraph() - { - /* Data. */ - $labels = array(); - $data = $this->_data; - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - foreach ($row as $colId => $value) { - if (!preg_match('/__(header|result).*__/', $colId)) { - $labels[$colId] = $value; - } - } - } - if (preg_match('/__(header|result).*__/', $rowId) && $rowId != '__resulttotal__') { - unset($data[$rowId]); - } else { - $labels[$rowId] = isset($row['__header__']) ? $row['__header__'] : $rowId; - unset($data[$rowId]['__header__']); - } - } - $this->data = $data; - - /* Additional params. */ - $this->setParam('graph', 'Bar'); - $this->setParam('stacked', 'false'); - $this->setParam('labels', $labels); - - return true; - } - -} diff --git a/fima/lib/Report/PeriodOverview.php b/fima/lib/Report/PeriodOverview.php deleted file mode 100644 index 7f77d1122..000000000 --- a/fima/lib/Report/PeriodOverview.php +++ /dev/null @@ -1,272 +0,0 @@ - - * @package Fima - */ -class Fima_Report_PeriodOverview extends Fima_Report { - - /* - * Constructs a new PeriodOverview Report. - */ - function Fima_Report_PeriodOverview($params = array()) - { - $this->_params = $params; - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Get account types. */ - $accounttypes = Fima::getAccountTypes(); - - /* Params. */ - if (($display = $this->getParam('display')) === null) { - return PEAR::raiseError(_("No display type")); - } - $display = explode('_', $display); - $posting_account = $this->getParam('posting_account'); - $period_start = ($display[0] == 'reference') ? $this->getParam('reference_start') : $this->getParam('period_start'); - $period_end = ($display[0] == 'reference') ? $this->getParam('reference_end') : $this->getParam('period_end'); - $display = ($display[0] == 'reference') ? $display[1] : $display[0]; - $cumulate = $this->getParam('cumulate'); - $nullrows = $this->getParam('nullrows'); - $yearly = $this->getParam('yearly'); - $graph = $this->getParam('graph'); - $datefmt = $yearly ? '%Y' : Fima::convertDateToPeriodFormat($GLOBALS['prefs']->getValue('date_format')); - $sortby = $this->getParam('sortby'); - $sortdir = $this->getParam('sortdir'); - - /* Rows. */ - $rows = array(); - for ($period = $period_start; $period <= $period_end; $period = strtotime($yearly ? '+1 year' : '+1 month', $period)) { - $rows[strftime($yearly ? '%Y' : '%Y%m', $period)] = strftime($datefmt, $period); - } - - /* Columns. */ - $cols = array(FIMA_ACCOUNTTYPE_INCOME, FIMA_ACCOUNTTYPE_EXPENSE); - $colheaders = array('__header__' => _("Period")); - $coldummy = array(); - $groups = array('0' => "%s", '1' => "e.o. %s", 'total' => "Total %s"); - foreach ($groups as $groupId => $group) { - foreach ($cols as $colPos => $colId) { - $coldummy[$colId . $groupId] = 0; - $colheaders[$colId . $groupId] = sprintf($group, $accounttypes[$colId]); - } - $coldummy['__result' . $groupId . '__'] = 0; - $colheaders['__result' . $groupId . '__'] = sprintf($group, _("Result")); - } - $colheaders['__resultasset__'] = _("Asset Result"); - $coldummy['__resultasset__'] = 0; - - /* Initialize matrix. */ - $data = array(); - $data['__headersort__'] = $colheaders; - foreach ($rows as $rowId => $rowLabel) { - $data[$rowId] = array('__header__' => $rowLabel) + $coldummy; - } - - /* Results. */ - $groups = array('0', '1'); - $total = array('__header__' => _("Total Result")) + $coldummy; - foreach ($groups as $group) { - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', $cols); - $filters[] = array('type', $display); - $filters[] = array('eo', $group); - if ($period_start !== null) { - $filters[] = array('date', (int)$period_start, '>='); - } - if ($period_end !== null) { - $filters[] = array('date', (int)$period_end, '<='); - } - - $result = Fima::getResults(array('account_type', $yearly ? 'date_year' : 'date_month'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $data[$rowId][$colId . $group] = $value; - $data[$rowId]['__result' . $group . '__'] += $value; - $total[$colId . $group] += $value; - $total['__result' . $group . '__'] += $value; - } - } - } - - /* Totals. */ - $data['__resulttotal__'] = $total; - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - continue; - } - foreach ($cols as $colId) { - $data[$rowId][$colId . 'total'] = $data[$rowId][$colId . '0'] + $data[$rowId][$colId . '1']; - - } - $data[$rowId]['__resulttotal__'] = $data[$rowId]['__result0__'] + $data[$rowId]['__result1__']; - } - - /* Asset Results. */ - $filters = array(); - $filters[] = array('account_type', FIMA_ACCOUNTTYPE_ASSET, '<>'); - $filters[] = array('type', $display); - if ($period_start !== null) { - $filters[] = array('date', (int)$period_start, '<'); - } - - $result = Fima::getResults(array('type'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - $assetresult = 0; - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - $assetresult += $value; - } - } - - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - continue; - } - if (!preg_match('/__result.*__/', $rowId)) { - $assetresult += $data[$rowId]['__resulttotal__']; - } - $data[$rowId]['__resultasset__'] = $assetresult; - } - - /* Null Rows and Cumulate. */ - if (!$nullrows || $cumulate) { - $cumulatevalue = $coldummy; - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - continue; - } - $isnullrow = true; - foreach ($row as $colId => $value) { - if (preg_match('/__(header).*__/', $colId) || $colId == '__resultasset__') { - continue; - } - if ($cumulate) { - $data[$rowId][$colId] += $cumulatevalue[$colId]; - $cumulatevalue[$colId] = $data[$rowId][$colId]; - } - if ($data[$rowId][$colId] != 0) { - $isnullrow = false; - } - } - if (!$nullrows && $isnullrow) { - unset($data[$rowId]); - } - } - } - - /* Sorting. */ - if ($sortby === null || !isset($colheaders[$sortby])) { - $sortby = $this->setParam('sortby', '__header__'); - } - if ($sortdir === null) { - $sortdir = $this->setParam('sortdir', FIMA_SORT_ASCEND); - } - if ($graph) { - $sortby = '__header__'; - $sortdir = FIMA_SORT_ASCEND; - } - - $x = -1; - $sortIndex = array(); - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - $x++; - $sortIndex[$x] = array($rowId => $row[$sortby]); - $x++; - } else { - if (!isset($sortIndex[$x])) { - $sortIndex[$x] = array(); - } - $sortIndex[$x][$rowId] = $row[$sortby]; - } - } - - foreach ($sortIndex as $indexId => $indexGroup) { - if (count($indexGroup) > 0) { - if ($sortdir) { - arsort($indexGroup); - } else { - asort($indexGroup); - } - } - foreach ($indexGroup as $rowId => $index) { - $this->_data[$rowId] = $data[$rowId]; - } - } - - return true; - } - - /* - * Output the graph. - * - * @return mixed True or PEAR Error - */ - function _getGraph() - { - /* Data. */ - $display = explode('_', $this->getParam('display')); - $display = ($display[0] == 'reference') ? $display[1] : $display[0]; - $postingtypes = Fima::getPostingTypes(); - - $labels = array(); - $data = $this->_data; - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - foreach ($row as $colId => $value) { - if (!(preg_match('/__(header|result).*__/', $colId) && $colId != '__resulttotal__')) { - $labels[$colId] = $value; - } - } - } - if (preg_match('/__(header|result).*__/', $rowId)) { - unset($data[$rowId]); - } else { - $labels[$rowId] = isset($row['__header__']) ? $row['__header__'] : $rowId; - foreach ($row as $colId => $value) { - if (preg_match('/__(header|result).*__/', $colId) && $colId != '__resulttotal__') { - unset($data[$rowId][$colId]); - } - } - } - } - $this->data = $data; - - /* Additional params. */ - $this->setParam('graph', 'Line'); - $this->setParam('labels', $labels); - $this->setParam('subtitle', $postingtypes[$display]); - - return true; - } - -} diff --git a/fima/lib/Report/Trend.php b/fima/lib/Report/Trend.php deleted file mode 100644 index b67b06ed1..000000000 --- a/fima/lib/Report/Trend.php +++ /dev/null @@ -1,323 +0,0 @@ - - * @package Fima - */ -class Fima_Report_Trend extends Fima_Report { - - /* - * Constructs a new Trend Report. - */ - function Fima_Report_Trend($params = array()) - { - $this->_params = $params; - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Get account types, posting types and accounts. */ - $accounttypes = Fima::getAccountTypes(); - $accounts = Fima::listAccounts(); - $accountIndex = array(); - foreach ($accounts as $accountId => $account) { - $accountIndex[$account['number']] = $accountId; - } - $groups = array(FIMA_ACCOUNTTYPE_INCOME, FIMA_ACCOUNTTYPE_EXPENSE); - - /* Params. */ - if (($display = $this->getParam('display')) === null) { - return PEAR::raiseError(_("No display type")); - } - $display = explode('_', $display); - $posting_account = $this->getParam('posting_account'); - $period_start = ($display[0] == 'reference') ? $this->getParam('reference_start') : $this->getParam('period_start'); - $period_end = ($display[0] == 'reference') ? $this->getParam('reference_end') : $this->getParam('period_end'); - $display = ($display[0] == 'reference') ? $display[1] : $display[0]; - $cumulate = $this->getParam('cumulate'); - $nullrows = $this->getParam('nullrows'); - $subaccounts = $this->getParam('subaccounts'); - $graph = $this->getParam('graph'); - $yearly = $this->getParam('yearly'); - $datefmt = $yearly ? '%Y' : Fima::convertDateToPeriodFormat($GLOBALS['prefs']->getValue('date_format')); - $sortby = $this->getParam('sortby'); - $sortdir = $this->getParam('sortdir'); - - /* Rows. */ - // accounts (dynamically) - - /* Columns. */ - $cols = array(); - $colheaders = array('__header__' => _("Account")); - $coldummy = array(); - for ($period = $period_start; $period <= $period_end; $period = strtotime($yearly ? '+1 year' : '+1 month', $period)) { - $colId = strftime($yearly ? '%Y' : '%Y%m', $period); - $cols[] = $colId; - $colheaders[$colId] = strftime($datefmt, $period); - $coldummy[$colId] = 0; - } - $colheaders['__result__'] = _("Total Result"); - $coldummy['__result__'] = 0; - - /* Initialize matrix. */ - $data = array(); - $data['__headersort__'] = $colheaders; - $datagroups = array(FIMA_ACCOUNTTYPE_INCOME => array(), FIMA_ACCOUNTTYPE_EXPENSE => array()); - // add parent accounts - if ($posting_account) { - foreach ($posting_account as $accountId => $account) { - if ($accounts[$account]['parent_id']) { - $posting_account[] = $accounts[$account]['parent_id']; - } - } - } - foreach ($accounts as $accountId => $account) { - if ($posting_account) { - if (!in_array($account['account_id'], $posting_account)) { - continue; - } - } - if ($account['type'] == FIMA_ACCOUNTTYPE_ASSET) { - continue; - } - if ($account['parent_id'] === null || !isset($accounts[$account['parent_id']])) { - $datagroups[$account['type']][$account['number']] = array('__header__' => $account['label']) + $coldummy; - if ($subaccounts) { - $datagroups[$account['type']][$account['number']]['__subaccounts__'] = array(); - } - } elseif ($subaccounts) { - $datagroups[$account['type']][$accounts[$account['parent_id']]['number']]['__subaccounts__'][$account['number']] = array('__header__' => ' '.$account['label']) + $coldummy; - } - } - foreach ($datagroups as $datagroupId => $datagroup) { - $datagroups[$datagroupId]['__result' . $datagroupId . '__'] = array('__header__' => sprintf(_("%s Result"), $accounttypes[$datagroupId])) + $coldummy; - $data += $datagroups[$datagroupId]; - } - - /* Results. */ - foreach ($groups as $group) { - $filters = array(); - if ($posting_account) { - $filters[] = array('account', $posting_account); - } - $filters[] = array('account_type', $group); - $filters[] = array('type', $display); - if ($period_start !== null) { - $filters[] = array('date', (int)$period_start, '>='); - } - if ($period_end !== null) { - $filters[] = array('date', (int)$period_end, '<='); - } - - $result = Fima::getResults(array($yearly ? 'date_year' : 'date_month', $subaccounts ? 'account_number' : 'account_parent'), $filters); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - foreach ($result as $rowId => $row) { - foreach ($row as $colId => $value) { - if (isset($data[$rowId])) { - $data[$rowId][$colId] += $value; - $data[$rowId]['__result__'] += $value; - } elseif (($parentId = $accounts[$accountIndex[$rowId]]['parent_id']) !== null) { - $data[$accounts[$parentId]['number']][$colId] += $value; - $data[$accounts[$parentId]['number']]['__result__'] += $value; - if ($subaccounts) { - $data[$accounts[$parentId]['number']]['__subaccounts__'][$rowId][$colId] += $value; - $data[$accounts[$parentId]['number']]['__subaccounts__'][$rowId]['__result__'] += $value; - } - } - $data['__result' . $group . '__'][$colId] += $value; - $data['__result' . $group . '__']['__result__'] += $value; - } - } - } - - /* Totals. */ - $data['__resulttotal__'] = array('__header__' => _("Total Result")) + $coldummy; - foreach ($cols as $colId) { - foreach ($groups as $groupId => $group) { - $data['__resulttotal__'][$colId] += $data['__result' . $group . '__'][$colId]; - $data['__resulttotal__']['__result__'] += $data['__result' . $group . '__'][$colId]; - } - } - - /* Null Rows and Cumulate. */ - if (!$nullrows || $cumulate) { - foreach ($data as $rowId => $row) { - if (preg_match('/__(header).*__/', $rowId)) { - continue; - } - $cumulatevalue = 0; - $isnullrow = true; - foreach ($row as $colId => $value) { - if (preg_match('/__(header|result).*__/', $colId)) { - continue; - } - if ($colId == '__subaccounts__') { - if (count($value) > 0) { - foreach ($value as $subRowId => $subRow) { - $subcumulatevalue = 0; - $subisnullrow = true; - foreach ($subRow as $subColId => $subValue) { - if (preg_match('/__(header|result).*__/', $subColId)) { - continue; - } - if ($cumulate) { - $data[$rowId]['__subaccounts__'][$subRowId][$subColId] += $subcumulatevalue; - $subcumulatevalue = $data[$rowId]['__subaccounts__'][$subRowId][$subColId]; - } - if ($data[$rowId]['__subaccounts__'][$subRowId][$subColId] != 0) { - $subisnullrow = false; - } - } - if (!$nullrows && $subisnullrow) { - unset($data[$rowId]['__subaccounts__'][$subRowId]); - } - } - } - } else { - if ($cumulate) { - $data[$rowId][$colId] += $cumulatevalue; - $cumulatevalue = $data[$rowId][$colId]; - } - if ($data[$rowId][$colId] != 0) { - $isnullrow = false; - } - } - } - if (!$nullrows && $isnullrow) { - unset($data[$rowId]); - } - } - } - - /* Sorting. */ - if ($sortby === null || !isset($colheaders[$sortby])) { - $sortby = $this->setParam('sortby', '__header__'); - } - if ($sortdir === null) { - $sortdir = $this->setParam('sortdir', FIMA_SORT_ASCEND); - } - $x = -1; - $sortIndex = array(); - foreach ($data as $rowId => $row) { - if (preg_match('/__(header|result).*__/', $rowId)) { - $x++; - $sortIndex[$x] = array($rowId => $row[$sortby]); - $x++; - } else { - if (!isset($sortIndex[$x])) { - $sortIndex[$x] = array(); - } - $sortIndex[$x][$rowId] = $row[$sortby]; - } - } - - foreach ($sortIndex as $indexId => $indexGroup) { - if (count($indexGroup) > 0) { - if ($sortdir) { - arsort($indexGroup); - } else { - asort($indexGroup); - } - } - foreach ($indexGroup as $rowId => $index) { - $this->_data[$rowId] = $data[$rowId]; - if (isset($data[$rowId]['__subaccounts__'])) { - if (count($data[$rowId]['__subaccounts__']) > 0) { - $subSortIndex = array(); - foreach ($data[$rowId]['__subaccounts__'] as $subId => $sub) { - $subSortIndex[$subId] = $sub[$sortby]; - } - if ($sortdir) { - arsort($subSortIndex); - } else { - asort($subSortIndex); - } - - foreach ($subSortIndex as $subId => $sub) { - $this->_data[$subId] = $data[$rowId]['__subaccounts__'][$subId]; - } - } - } - unset($this->_data[$rowId]['__subaccounts__']); - } - } - - return true; - } - - /* - * Output the graph. - * - * @return mixed True or PEAR Error - */ - function _getGraph() - { - /* Data. */ - $display = explode('_', $this->getParam('display')); - $display = ($display[0] == 'reference') ? $display[1] : $display[0]; - $postingtypes = Fima::getPostingTypes(); - - $labels = array(); - $data = $this->_data; - $sum = array(); - foreach ($data as $rowId => $row) { - if (preg_match('/__header.*__/', $rowId)) { - foreach ($row as $colId => $value) { - if (!(preg_match('/__(header|result).*__/', $colId) && $colId != '__resulttotal__')) { - $labels[$colId] = $value; - } - } - } - if (preg_match('/__(header|result).*__/', $rowId)) { - unset($data[$rowId]); - } else { - $labels[$rowId] = isset($row['__header__']) ? $row['__header__'] : $rowId; - if ($data[$rowId]['__result__'] != 0) { - $sum[$rowId] = $data[$rowId]['__result__']; - } - unset($data[$rowId]['__header__']); - unset($data[$rowId]['__result__']); - } - } - - // grouping - asort($sum); - $topdata = array_slice($sum, 0, 5, true) + array_slice($sum, -5, 5, true); - foreach ($data as $rowId => $row) { - if (!isset($topdata[$rowId])) { - unset($data[$rowId]); - } - } - - $this->data = $data; - - /* Additional params. */ - $this->setParam('graph', 'Line'); - $this->setParam('labels', $labels); - $this->setParam('subtitle', $postingtypes[$display]); - $this->setParam('invert', true); - - return true; - } - -} diff --git a/fima/lib/ReportGraph.php b/fima/lib/ReportGraph.php deleted file mode 100644 index 2ca7a540a..000000000 --- a/fima/lib/ReportGraph.php +++ /dev/null @@ -1,191 +0,0 @@ - - * @package Fima - */ -class Fima_ReportGraph { - - /** - * Hash containing report parameters. - * - * @var array - */ - var $_params = array(); - - /** - * Array containing the data after execution of the report. - * - * @var mixed - */ - var $_data = array(); - - /** - * Bytes containing the report graph after execution of the report. - * - * @var bytes - */ - var $_graph = null; - var $_plotarea = null; - var $_legend = null; - - /** - * Constructor - just store the $params in our newly-created - * object. All other work is done by initialize(). - * - * @param array $data The dataset. - * @param array $params Any parameters needed for this driver. - */ - function Fima_ReportGraph($data = array(), $params = array(), $errormsg = null) - { - $this->_data = $data; - $this->_params = $params; - if (is_null($errormsg)) { - $this->_errormsg = _("The Finances report graphs are not currently available."); - } else { - $this->_errormsg = $errormsg; - } - } - - /* - * Executes the report. - * - * @return mixed True or PEAR Error - */ - function execute() - { - /* Create graph. */ - $this->_graph =& Image_Graph::factory('graph', array($this->_style['width'], $this->_style['height'])); - $this->_graph->displayErrors(); - - /* Add Font. */ - $font =& $this->_graph->addNew('font', $this->_style['font-family']); - $font->setColor($this->_style['font-color']); - $font->setSize($this->_style['font-size']); - $this->_graph->setFont($font); - - /* Plot and Legend. */ - $title =& Image_Graph::factory('title', array(isset($this->_params['title']) ? $this->_params['title'] : _("Report"), $this->_style['header-size'])); - $title->setAlignment(IMAGE_GRAPH_ALIGN_BOTTOM | IMAGE_GRAPH_ALIGN_CENTER_X); - $subtitle =& Image_Graph::factory('title', array(isset($this->_params['subtitle']) ? $this->_params['subtitle'] : '', $this->_style['subheader-size'])); - $this->_plotarea =& Image_Graph::factory('plotarea'); - $this->_legend =& Image_Graph::factory('legend'); - $this->_graph->add( - Image_Graph::vertical( - Image_Graph::vertical( - $title, - $subtitle, - 60 - ), - Image_Graph::vertical( - $this->_plotarea, - $this->_legend, - 88 - ), - 10 - ) - ); - $this->_legend->setPlotarea($this->_plotarea); - $this->_legend->setAlignment(IMAGE_GRAPH_ALIGN_CENTER); - - /* Execute. */ - $execute = $this->_execute(); - if (is_a($execute, 'PEAR_Error')) { - return $execute; - } - - /* Log the execution of the report in the history log. */ - $GLOBALS['injector']->getInstance('Horde_History')->log('fima:reportgraph', array('action' => 'execute'), true); - - return true; - } - - /** - * Returns the graph of this report (if any). - * - * @return bytes Image data - */ - function getGraph() - { - header('Expires: Mon, 01 Jan 1970 00:00:00 GMT'); - header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - header('Pragma: public'); - header('Cache-Control: no-store, no-cache, must-revalidate'); - header('Cache-Control: pre-check=0, post-check=0, max-age=0'); - header('Content-Type: image/jpeg'); - header('Accept-Ranges: bytes'); - #header('Content-Length: ' . ); - header('Content-Disposition: inline'); - - $this->_graph->done(); - - return true; - } - - /** - * Initialization of the report. - * - * @return boolean True on success; PEAR_Error on failure. - */ - function initialize() - { - /* Load styles. */ - include_once($GLOBALS['registry']->get('themesfs') . '/report.inc'); - $this->_style = $style; - } - - /** - * Attempts to return a concrete Fima_ReportGraph instance based on $driver. - * - * @param string $driver The type of the concrete Fima_ReportGraph subclass - * to return. The class name is based on the - * storage driver ($driver). The code is - * dynamically included. - * - * @param array $data The dataset. - * @param array $params (optional) A hash containing any additional - * configuration or connection parameters a - * subclass might need. - * - * @return mixed The newly created concrete Fima_Driver instance, or - * false on an error. - */ - function &factory($driver = null, $data = null, $params = null) - { - if ($driver === null) { - $report = new Fima_ReportGraph($data, $params, _("No report driver loaded")); - return $report; - } - - require_once dirname(__FILE__) . '/ReportGraph/' . $driver . '.php'; - $class = 'Fima_ReportGraph_' . $driver; - if (class_exists($class)) { - $report = new $class($data, $params); - $result = $report->initialize(); - if (is_a($result, 'PEAR_Error')) { - $report = new Fima_ReportGraph($data, $params, sprintf(_("The Finances report graphs are not currently available: %s"), $result->getMessage())); - } - } else { - $report = new Fima_ReportGraph($data, $params, sprintf(_("Unable to load the definition of %s."), $class)); - } - - return $report; - } - -} diff --git a/fima/lib/ReportGraph/Bar.php b/fima/lib/ReportGraph/Bar.php deleted file mode 100644 index 0a3feede7..000000000 --- a/fima/lib/ReportGraph/Bar.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @package Fima - */ -class Fima_ReportGraph_Bar extends Fima_ReportGraph { - - /* - * Constructs a new Bar ReportGraph. - */ - function Fima_ReportGraph_Bar($data = array(), $params = array()) - { - $this->_data = $data; - $this->_params = $params; - - if (!isset($this->_params['invert'])) { - $this->_params['invert'] = false; - } - } - - /* - * Executes the report graph. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Grid. */ - $grid =& $this->_plotarea->addNew('line_grid'); - $gridfill =& Image_Graph::factory('Image_Graph_Fill_Array'); - $gridfill->addColor($this->_style['grid']); - $grid->setFillStyle($gridfill); - - /* Datasets. */ - $datasets = array(); - $datasetindex = array(); - $ix = 0; - foreach ($this->_data as $rowId => $row) { - foreach ($row as $colId => $value) { - $xd = $this->_params['invert'] ? $rowId : $colId; - $xx = $this->_params['invert'] ? $colId : $rowId; - if (!isset($datasetindex[$xd])) { - $datasetindex[$xd] = $ix++; - $datasets[$datasetindex[$xd]] =& Image_Graph::factory('dataset'); - $datasets[$datasetindex[$xd]]->setName($this->_params['labels'][$xd]); - } - $datasets[$datasetindex[$xd]]->addPoint($this->_params['labels'][$xx], $value); - } - } - - $plot =& $this->_plotarea->addNew('bar', $params['stacked'] ? array($datasets, 'stacked') : array($datasets)); - $plot->setLineColor($this->_style['line']); - - /* Fill style. */ - $fill =& Image_Graph::factory('Image_Graph_Fill_Array'); - foreach ($datasetindex as $key => $value) { - if (isset($this->_style[$key])) { - $fill->addColor($this->_style[$key]); - } else { - $fill->addColor($this->_style['color' . $value]); - } - } - $plot->setFillStyle($fill); - - /* Axis. */ - $axisx =& $this->_plotarea->getAxis(IMAGE_GRAPH_AXIS_X); - $axisy =& $this->_plotarea->getAxis(IMAGE_GRAPH_AXIS_Y); - $axisy->showLabel(IMAGE_GRAPH_LABEL_ZERO); - $axisy->setDataPreprocessor(Image_Graph::factory('Image_Graph_DataPreprocessor_Function', create_function('$value', 'return Fima::convertValueToAmount($value);'))); - - return true; - } - -} diff --git a/fima/lib/ReportGraph/Line.php b/fima/lib/ReportGraph/Line.php deleted file mode 100644 index 9ee2599d1..000000000 --- a/fima/lib/ReportGraph/Line.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @package Fima - */ -class Fima_ReportGraph_Line extends Fima_ReportGraph { - - /* - * Constructs a new Line ReportGraph. - */ - function Fima_ReportGraph_Line($data = array(), $params = array()) - { - $this->_data = $data; - $this->_params = $params; - - if (!isset($this->_params['invert'])) { - $this->_params['invert'] = false; - } - } - - /* - * Executes the report graph. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Grid. */ - $grid =& $this->_plotarea->addNew('line_grid'); - $gridfill =& Image_Graph::factory('Image_Graph_Fill_Array'); - $gridfill->addColor($this->_style['grid']); - $grid->setFillStyle($gridfill); - - /* Datasets. */ - $datasets = array(); - $datasetindex = array(); - $ix = 0; - foreach ($this->_data as $rowId => $row) { - foreach ($row as $colId => $value) { - $xd = $this->_params['invert'] ? $rowId : $colId; - $xx = $this->_params['invert'] ? $colId : $rowId; - if (!isset($datasetindex[$xd])) { - $datasetindex[$xd] = $ix++; - $datasets[$datasetindex[$xd]] =& Image_Graph::factory('dataset'); - $datasets[$datasetindex[$xd]]->setName($this->_params['labels'][$xd]); - } - $datasets[$datasetindex[$xd]]->addPoint($this->_params['labels'][$xx], $value); - } - } - - /* Line style. */ - foreach ($datasetindex as $key => $value) { - $plot =& $this->_plotarea->addNew('line', $datasets[$value]); - $plot->setLineColor($this->_style['line']); - - $line =& Image_Graph::factory('Image_Graph_Line_Solid', isset($this->_style[$key]) ? $this->_style[$key] : $this->_style['color' . $value]); - $line->setThickness(2); - $plot->setLineStyle($line); - } - - /* Axis. */ - $axisx =& $this->_plotarea->getAxis(IMAGE_GRAPH_AXIS_X); - $axisx->setFontAngle('vertical'); - $axisx->setLabelOption('offset', -20); - $axisy =& $this->_plotarea->getAxis(IMAGE_GRAPH_AXIS_Y); - $axisy->showLabel(IMAGE_GRAPH_LABEL_ZERO); - $axisy->setDataPreprocessor(Image_Graph::factory('Image_Graph_DataPreprocessor_Function', create_function('$value', 'return Fima::convertValueToAmount($value);'))); - - return true; - } - -} diff --git a/fima/lib/ReportGraph/Pie.php b/fima/lib/ReportGraph/Pie.php deleted file mode 100644 index 657681854..000000000 --- a/fima/lib/ReportGraph/Pie.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @package Fima - */ -class Fima_ReportGraph_Pie extends Fima_ReportGraph { - - /* - * Constructs a new Pie ReportGraph. - */ - function Fima_ReportGraph_Pie($data = array(), $params = array()) - { - $this->_data = $data; - $this->_params = $params; - } - - /* - * Executes the report graph. - * - * @return mixed True or PEAR Error - */ - function _execute() - { - /* Datasets. */ - $datasets = array(); - $datasetindex = array(); - $x = 0; - foreach ($this->_data as $ix => $dataset) { - $datasets[$ix] =& Image_Graph::factory('dataset'); - foreach ($dataset as $key => $value) { - $datasetindex[$x++] = $key; - $datasets[$ix]->addPoint($this->_params['labels'][$key], $value); - } - } - $plot =& $this->_plotarea->addNew('pie', array($datasets)); - $plot->setLineColor($this->_style['line']); - - /* Fill style. */ - $fill =& Image_Graph::factory('Image_Graph_Fill_Array'); - foreach ($datasetindex as $key => $value) { - if (isset($this->_style[$value])) { - $fill->addColor($this->_style[$value]); - } else { - $fill->addColor($this->_style['color' . $key]); - } - } - $plot->setFillStyle($fill); - - /* Axis. */ - $this->_plotarea->hideAxis(); - - /* Explode. */ - if (isset($this->_params['explode'])) { - if (is_int($this->_params['explode']) || is_array($this->_params['explode'])) { - $plot->explode($this->_params['explode']); - } else { - $plot->explode(10, $this->_params['explode']); - } - } - - /* Marker. */ - if ($this->_params['marker']) { - $marker =& $plot->addNew('Image_Graph_Marker_Value', IMAGE_GRAPH_PCT_Y_TOTAL); - $marker->setDataPreprocessor(Image_Graph::factory('Image_Graph_DataPreprocessor_Formatted', '%0.1f%%')); - $marker->setFontSize($this->_style['font-size']); - $pointingmarker =& $plot->addNew('Image_Graph_Marker_Pointing_Angular', array(30, &$marker)); - $plot->setMarker($pointingmarker); - } - - return true; - } - -} diff --git a/fima/lib/UI/VarRenderer/fima.php b/fima/lib/UI/VarRenderer/fima.php deleted file mode 100644 index 4d9b57277..000000000 --- a/fima/lib/UI/VarRenderer/fima.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @package Fima - */ -class Horde_Core_Ui_VarRenderer_Fima extends Horde_Core_Ui_VarRenderer_Html { - - protected function _renderVarInput_fima_dspostings($form, &$var, &$vars) - { - $varname = @htmlspecialchars($var->getVarName(), ENT_QUOTES, $this->_charset); - $value = $var->getValue($vars); - - return sprintf('
', - $varname, - $varname, - $value['type'] == 'delete' ? ' checked="checked"' : '', - $varname, - _("Delete postings.")) - . sprintf('
', - $varname, - $varname, - $value['type'] == 'shift' ? ' checked="checked"' : '', - $varname, - _("Shift postings to")) - . Fima::buildAccountWidget($varname . '[account]', $value['account'], 'onchange="document.getElementsByName(\'dspostings[type]\')[1].checked = true;"', false, false, array(array('type', $vars->get('type')))); - } - - protected function _renderVarInput_fima_dssubaccounts($form, &$var, &$vars) - { - $varname = @htmlspecialchars($var->getVarName(), ENT_QUOTES, $this->_charset); - $value = $var->getValue($vars); - - return sprintf('
', - $varname, - $varname, - $value['type'] == 'none' ? ' checked="checked"' : '', - $varname, - _("Keep subaccounts and postings.")) - . sprintf('
', - $varname, - $varname, - $value['type'] == 'delete' ? ' checked="checked"' : '', - $varname, - _("Delete subaccounts and postings.")) - . sprintf('
', - $varname, - $varname, - $value['type'] == 'shift' ? ' checked="checked"' : '', - $varname, - _("Delete subaccounts and shift postings to")) - . Fima::buildAccountWidget($varname . '[account]', $value['account'], 'onchange="document.getElementsByName(\'dssubaccounts[type]\')[2].checked = true;"', false, false, array(array('type', $vars->get('type')))); - } - -} diff --git a/fima/lib/base.php b/fima/lib/base.php deleted file mode 100644 index 2acae93c6..000000000 --- a/fima/lib/base.php +++ /dev/null @@ -1,53 +0,0 @@ -pushApp('fima', array('logintasks' => true)); -} catch (Horde_Exception $e) { - $registry->authenticateFailure('fima', $e); -} -$conf = &$GLOBALS['conf']; -@define('FIMA_TEMPLATES', $registry->get('templates')); - -// Find the base file path of Fima. -if (!defined('FIMA_BASE')) { - @define('FIMA_BASE', dirname(__FILE__) . '/..'); -} - -// Fima base library -require_once FIMA_BASE . '/lib/Driver.php'; - -// Start output compression. -Horde::compressOutput(); - -// Set the timezone variable. -$registry->setTimeZone(); - -// Create a share instance. -$GLOBALS['fima_shares'] = $GLOBALS['injector']->getInstance('Horde_Share_Factory')->getScope(); - -Fima::initialize(); diff --git a/fima/locale/.htaccess b/fima/locale/.htaccess deleted file mode 100644 index 3a4288278..000000000 --- a/fima/locale/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/fima/locale/de/LC_MESSAGES/fima.mo b/fima/locale/de/LC_MESSAGES/fima.mo deleted file mode 100644 index c94b247197894d54decc82ac2a0b802ee4b01451..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176647 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\n"; - //nachdem der Ordner vollstaendig ausgelesen wurde, wird dieser geschlossen - closedir($dir_handle); - } - else { - echo "Error: Can't open directory \"$dir_name\"!"; - } -} - -//diese Funktion liest den temporaeren Ordner von Kastalia aus -//und loescht alle Dateien die zu lange existieren -function CleanDirectory($dir_name) { - //die Konfigurationsdatei von Kastalia wird includiert - //damit die Konfigurationen auch innerhalb dieser Funktion benutzt werden koennen - require(KASTALIA_BASE . '/config/conf.php'); - if($dir_handle = opendir($dir_name)) { - //der Inhalt des Ordners wird in dieser Schleife durchgegangen und jedes Element bearbeitet - //falls es sich um eine Datei handelt, wird die ctime von dieser Datei ermittelt - while(false !== ($file = readdir($dir_handle))) { - //Ueberpruefung ob es sich bei dem Element um eine Datei handelt (und keine .htaccess Datei) - if($file != "." && $file != ".." && $file != ".htaccess" && is_file($dir_name . '/' . $file)) { - //hier wird die ctime der Datei fuer weitere Pruefungen ermittelt - if($file_ctime = filectime($dir_name . '/' . $file)) { - //die ctime der Datei (wird angegeben in Sekunden seit January 1 1970 00:00:00 GMT) - //wird mit der in der Config angegebenen Dauer (in Minuten) - //wie lange eine temporaere Datei existieren darf addiert... - $file_ctime = $file_ctime + (60 * $conf['upload']['tempctime']); - //... um zu ueberpruefen, ob die aktuelle Zeit in Sekunden seit der Unix Epoche - //(January 1 1970 00:00:00 GMT) groesser oder gleich der errechneten Zeit ist - //die eine temporaere Datei existieren darf - if($file_ctime <= time()) { - //wenn die aktuelle Zeit in Sekunden seit der Unix Epoche groesser ist - //wird die temporaere Datei geloescht - if(!unlink($dir_name . '/' . $file)) { - //falls ein Fehler beim loeschen auftritt, wird eine Error Nachricht ausgegeben - //aber das Skript nicht abgebrochen, da der Rest noch abgearbeitet werden soll - echo "Error: Unable to delete temporary file!
\n"; - echo "This constitutes a breach of security because the content of the uploaded file stored unencrypted.
\n"; - echo "Please contact the administrator to have the temporary file " . $dir_name . '/' . $file . " deleted.\n"; - } - } - } - else { - //falls die ctime der Datei nicht ermittelt werden kann, wird eine Nachricht ausgegeben - //aber nicht abgebrochen, da der Rest des Skriptes noch abgearbeitet werden soll - echo "Error: Unable to get the ctime of the file: " . $dir_name . '/' . $file . "!
"; - echo "This constitutes a breach of security because the uploaded file will not be deleted and the content stored unencrypted.
\n"; - echo "Please contact the administrator to have the file deleted.\n"; - } - } - } - } - else { - echo "Error: Can't open directory \"$dir_name\"!"; - } -} -?> - - \ No newline at end of file diff --git a/kastalia/temp/.htaccess b/kastalia/temp/.htaccess deleted file mode 100644 index 3a4288278..000000000 --- a/kastalia/temp/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/kastalia/templates/common-footer.inc b/kastalia/templates/common-footer.inc deleted file mode 100644 index 108cecf8c..000000000 --- a/kastalia/templates/common-footer.inc +++ /dev/null @@ -1,3 +0,0 @@ -notify(array('listeners' => array('audio'))); ?> - - diff --git a/kastalia/templates/common-header.inc b/kastalia/templates/common-header.inc deleted file mode 100755 index 4f3571c73..000000000 --- a/kastalia/templates/common-header.inc +++ /dev/null @@ -1,32 +0,0 @@ -getCharset()); - header('Vary: Accept-Language'); -} -?> - - - - -' : '' ?> - - - - -get('name'); -if (!empty($title)) { - $page_title .= ' :: ' . $title; -} - -Horde::outputMetaTags(); -Horde::includeScriptFiles(); - -?> -<?php echo htmlspecialchars($page_title) ?> - - - - - diff --git a/kastalia/templates/menu.inc b/kastalia/templates/menu.inc deleted file mode 100755 index d96bb7137..000000000 --- a/kastalia/templates/menu.inc +++ /dev/null @@ -1,5 +0,0 @@ - - -notify(array('listeners' => 'status')) ?> diff --git a/kastalia/themes/graphics/directory_closed.gif b/kastalia/themes/graphics/directory_closed.gif deleted file mode 100755 index c4f1138bf9e9e3c0b491032059049950bdcb58dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 278 zcmZ?wbhEHbRAUfec+9~71Pu)hbLKFdJD2?b+?@aa=Y0SE{r~@S|8W4te>TZQsfi`2 zDGF)%MG7AIMJcHYi3J5YnaPPInfZAN-igH}i8+~xdU|?X8W|-e1y=g{873*I#d`Tg z>6#3RKUo;L7&sVoKsJNiz`)WhaME-2UW?afe~T(`R4h@EI36f+=ml$mO!%RM`_2+s zjSv5~G3dJLEaPInzVtcspB9nEEZ4O{lO&fNeA(=`Bvfmm!Lg*Oh7zj|0j`4&ul`uI zC1dBC7a>0HW>2@Th*PVsDXuSb@ON&jWhsd?GIB2NOX=@WjklO%Q94UFYtiD&12zI~zq diff --git a/kastalia/themes/graphics/directory_open.gif b/kastalia/themes/graphics/directory_open.gif deleted file mode 100644 index 09755aafcd40895a2615dd392f8833d0f1313ea2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210 zcmZ?wbhEHbRAUfec+9~71Pu)hbLKFdJD2?b+?@aa=Y0SE{r~@S|8W4tpDc`A3>*wP zAe|sH7+C5BPI|81Yw`N5wV1+--pL6P$2EH#U+7SS*+V83Q)Qy*y>wGugfu~Y62`xRI8UkI-YglJ~@on6)Ns`+`dh5maMiFv17?{el pEA#SAi&;8d8{PHw#nn=4yOU3W%PTA_tf;8i(9m$^%$fgSp!k!8k&A(yL5BedKx!G7 zoho+S`Dbv-b2YO>3&WalN5!sN>5R&eCC^%xN#1tK_c|Atd%9xr^2U40DZ-pB(;xAk Z{Lx$C^L)}u2@VrUzA2~PsxdHF0{{thEouM& diff --git a/kastalia/themes/graphics/file_enc.gif b/kastalia/themes/graphics/file_enc.gif deleted file mode 100644 index 8bd8bac3d84b7168a464495ce4e7ca46d08d47c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 664 zcmZ?wbhEHbRAUfeIF`@gpeAIiDQ#$I=&U0f7#J876ciB=(H^Q;66c+onmRc~c1nzF zT3T9WX6B3})%^VYxoO&SGYuCNSoT$<&Z>-9TkW)^%4}Vo^R^nx_4TgXYppgkxOH}R zZfx?{*>hh|}D{HE^Y}s;kUH#UrTd!|y z-o1PGogIA#4jj0*d*Z#lQ;r-t@?ih;hX;UY#-l^CpPgEE;lhQB7cbtrb?eTZJ9qEi z{ZBej{O9SNSX`2rlbNWHmS3dckzbUOs^C_Xn44OjUzE+Ikx^1oV5P60VUm(ste0Pu zuAiBgl3JlxkWpZtnU|56Q(~J9)vw8*_>+Z^i=m!DhXDvc5zN58qM^R2xuvzOy`!_M zjW;DPmbH6Qr+khKe{>e-P zG{DVJV0))QMof^Gi;!+w{{SeJqU3O;n}0?zQQrM+JJi zI$Nqs@V#!;ObYR~wzf5OiRftPpU`C(HtWZQgNKiC2nccUEh=bn>EISOD>)JHu;EC* K0yirYgEau9=SrRc diff --git a/kastalia/themes/graphics/kastalia.png b/kastalia/themes/graphics/kastalia.png deleted file mode 100644 index 6f44752eb4fb89799afff067acaa5d6a5021938f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 451 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 diff --git a/kastalia/themes/graphics/menu/upload.png b/kastalia/themes/graphics/menu/upload.png deleted file mode 100644 index 780a740c0b609e569c08ff11becd1b8a46e7ba3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 214 zcmV;{04e{8P)xxn{Q+WQaErgUPA z8|)g-;ltz(fos4Pngvh&0nG$e1A6F>;Hw*fvu=W~ZUoM{3Ep~ni!>RU)NNsPsTd&m zt3G0w+hVT%!3}Fn@2qge8=4KUI$k)TE8Nl&M?9hE)58l6SXBJ#E%rEn0eLaXT&gzj QQ~&?~07*qoM6N<$f~!|q!~g&Q diff --git a/kastalia/themes/screen.css b/kastalia/themes/screen.css deleted file mode 100755 index a219ca1bb..000000000 --- a/kastalia/themes/screen.css +++ /dev/null @@ -1,44 +0,0 @@ -a.kastalia_directory { - text-decoration: none; - font-weight: bold; - color: #000000; -} - -div.kastalia_filelist { - margin-left: 0px; -} - -img.kastalia_picture { - border: 0px; - margin-right: 2px; -} - -li.kastalia_directory { - list-style: none; - display: block; - padding-top: 5px; - padding-left: 4px; -} - -li.kastalia_file { -/* list-style: none;*/ - list-style-image: url('graphics/file.gif'); - padding-left: 4px; -} - -li.kastalia_file_enc { -/* list-style: none;*/ - list-style-image: url('graphics/file_enc.gif'); - padding-left: 4px; -} - -select.kastalia_upload { - width: 300px; -} - -ul.kastalia_root { - list-style-position: inside; - margin-left: 5px; - padding-left: 10px; - vertical-align: middle; -} \ No newline at end of file diff --git a/kastalia/upload.php b/kastalia/upload.php deleted file mode 100644 index e82ecbc1e..000000000 --- a/kastalia/upload.php +++ /dev/null @@ -1,207 +0,0 @@ - - */ - -//das absolute Kastalia directory wird als Konstante definiert -//um damit config Dateien zu includieren -@define('KASTALIA_BASE', dirname(__FILE__)); - -//die Basis von Kastalia wird includiert -//um die Anmeldung zu ueberpruefen -require_once(KASTALIA_BASE . '/lib/base.php'); -//die Konfigurationsdatei von Kastalia wird includiert -//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen -require(KASTALIA_BASE . '/config/conf.php'); -//das Menu von Kastalia wird includiert -//damit das Menu dem Benutzer angezeigt wird -require_once(KASTALIA_BASE . '/list.php'); - -echo "
Kastalia Datastore - Upload
\n"; -echo "
\n"; - -//nun wird ueberprueft, ob das hochladen von Dateien ueberhaupt erlaubt ist -//falls nicht, wird eine Meldung ausgegeben und das Skript beendet -if(!$conf['upload']['uploadenabled']) { - echo "File uploads are disabled!"; - exit(0); -} - -//hier wird ueberprueft, ob der Zielordner zum hochladen gesetzt ist -if(isset($_POST['kastalia_targetlocation'])) { - //hier wird mittels POST der uploadzielordner ermittelt - $kastalia_targetlocation = $_POST['kastalia_targetlocation']; - //Ueberpruefung nach den Zeichenfolgen "/." und "./" damit - //durch das Manipulieren der Variable kastalia_targetlocation - //keiner aus dem kastalia Datastore entkommen kann (durch Nutzung von "../") - if(strpos($kastalia_targetlocation,'/.') === false && strpos($kastalia_targetlocation,'./') === false) { - //ueberpruefung ob die Datei eine ".htaccess" ist, falls ja wird zur Sicherheit abgebrochen, damit niemand diese - //ueberschreiben kann oder damit regeln fuer den webserver festlegen kann - if(Kastalia::ReplaceSpecialChars($_FILES['userfile']['name']) != ".htaccess") { - //hier wird serverseitig ueberprueft, ob die hochgeladene Datei die Endung ".kastaliaenc" besitzt - //falls ja wird mit einem Fehler abgebrochen, da diese intern von Kastalia verwendet wird - //um von Kastalia verschluesselte Dateien ausfindig zu machen - if(substr(Kastalia::ReplaceSpecialChars($_FILES['userfile']['name']), -12) == ".kastaliaenc") { - echo "Error: File extension \".kastaliaenc\" not allowed!"; - exit(1); - } - //hier wird der absolute Pfad mit Dateiname (Sonderzeichen werden entfernt) zusammengesetzt - //wohin die Datei hochgeladen werden soll - $target_directory = $conf['datastore']['location'] . $kastalia_targetlocation; - $target_location = $target_directory . "/" . Kastalia::ReplaceSpecialChars($_FILES['userfile']['name']); - //diese Funktion fuehrt den Upload aus - UploadFile($target_location); - } - else { - echo "Error: .htaccess files not allowed for upload!"; - exit(1); - } - } - else { - echo "Error: \$kastalia_targetlocation in upload.php contains illegal characters!"; - exit(1); - } -} -//falls der Dateiname nicht gesetzt wurde, wird mit einer Fehlermeldung abgebrochen -else { - echo "Error: \$kastalia_targetlocation in upload.php is not set!"; - exit(1); -} - -//diese Funktion ueberprueft Fehler die beim upload vorkommen koennen -//und fuehrt den upload durch -function UploadFile($upload_target) { - //die Konfigurationsdatei von Kastalia wird includiert - require(KASTALIA_BASE . '/config/conf.php'); - if(!empty($_FILES)) { - switch ($_FILES['userfile']['error']) { - case 0: //UPLOAD_ERR_OK - //hier wird die in der Config eingestellte maximale Dateigroesse mit - //der Dateigroesse der hochgeladenen Datei abgeglichen - if($_FILES['userfile']['size'] <= $conf['upload']['maxfilesize']) { - //Sicherheitsueberpruefung ob Datei mittels HTTP POST hochgeladen wurde - //und nicht eine andere Datei weiterbearbeitet wird - if(is_uploaded_file($_FILES['userfile']['tmp_name'])) { - //hier wird ueberprueft ob der Upload verschluesselt gespeichert werden soll - if(isset($_POST['kastalia_secure_store']) && $_POST['kastalia_secure_store'] == true) { //SECURE STORE - //hier wird ueberprueft, ob das verschluesselte Speichern von Dateien ueberhaupt aktiviert ist - //falls nicht, wird die Weiterverarbeitung abgebrochen und eine Meldung ausgegeben - if(!$conf['upload']['securestore']) { - echo "Encryption/Decryption is disabled!"; - exit(1); - } - //sollte die Datei mit der Endung ".kastaliaenc" schon existieren, wird ein "_" an sie drangehaengt, - //damit die existierende Datei nicht ueberschrieben wird - while(file_exists($upload_target . ".kastaliaenc")) { - $upload_target = $upload_target . "_"; - } - //hier wird serverseitig ueberprueft ob das Passwort fuer die Verschluesselung leer ist - //falls ja, wird mit einem Fehler abgebrochen, da dies verboten ist (und die temporaere Datei von - //PHP automatisch geloescht) - if($_POST['kastalia_password'] == "") { - echo "Error: Empty passwords not allowed!"; - exit(1); - } - //die hochgeladene Datei wird nun ersteinmal in das temporaere Verzeichnis von Kastalia verschoben - //und mit der Endung "_kastalia" versehen - if(move_uploaded_file($_FILES['userfile']['tmp_name'], $conf['upload']['tempdir'] . "/" . basename($_FILES['userfile']['tmp_name']) . "_kastalia")) { - //die SESSION Variablen fuer die Verschluesselung werden gesetzt - $_SESSION['kastalia_mode'] = "encrypt"; //diese Variable gibt den Modus an in welchem das Skript encrypt_decrypt_files.php ausgefuehrt werden soll - $_SESSION['kastalia_input_name'] = $conf['upload']['tempdir'] . "/" . basename($_FILES['userfile']['tmp_name']) . "_kastalia"; //diese Variable gibt die zu verschluesselnde Datei an - $_SESSION['kastalia_output_name'] = $upload_target; //diese Variable gibt das Ziel fuer die verschluesselte Datei an - $_SESSION['kastalia_part_number'] = 0; //diese Variable gibt die aktuelle Verschluesselungsrunde an (die Beginnrunde ist immer 0) - $_SESSION['kastalia_key'] = $_POST['kastalia_password']; //diese Variable beinhaltet das Passwort, welches fuer die Verschluesselung benutzt wird - //mit der encrypt_decrypt_files.php wird die Verschluesselung fuer die Datei ausgefuehrt - //(diese besteht aus mehreren Teilschritten wobei der Browser automatisch das Skript in Intervallen neu aufruft) - include('encrypt_decrypt_files.php'); - } - else { - echo "Error: File couldn't be moved to temporary directory!"; - //Debuging - //print_r($_FILES); - exit(1); - } - } - else { //UNSECURE STORE - //sollte die Datei schon existieren, wird ein "_" an sie drangehaengt, - //damit die existierende Datei nicht ueberschrieben wird - while(file_exists($upload_target)) { - $upload_target = $upload_target . "_"; - } - //die hochgeladene Datei wird nun an die dafuer vorgesehene stelle kopiert - if(move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_target)) { - echo "File successfully stored under " . substr($upload_target, strlen($conf['datastore']['location'] . "/")) . " !\n"; - } - else { - echo "Error: File couldn't be moved!"; - //Debuging - //print_r($_FILES); - exit(1); - } - } - } - else { - echo "Error: Used file is not uploaded via HTTP POST!"; - exit(1); - } - - } - else { - echo "Error: The uploaded file exceeds the configured file size!"; - exit(1); - } - break; - case 1: //UPLOAD_ERR_INI_SIZE - echo "Error: The uploaded file exceeds the upload_max_filesize directive in php.ini!"; - exit(1); - break; - case '2': //UPLOAD_ERR_FORM_SIZE - echo "Error: The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form!"; - exit(1); - break; - case 3: //UPLOAD_ERR_PARTIAL - echo "Error: The file was only partially uploaded!"; - exit(1); - break; - case 4: //UPLOAD_ERR_NO_FILE - echo "Error: No file was uploaded!"; - exit(1); - break; - case 6: //UPLOAD_ERR_NO_TMP_DIR - echo "Error: Missing a temporary folder!"; - exit(1); - break; - case 7: //UPLOAD_ERR_CANT_WRITE - echo "Error: Failed to write file to disk!"; - exit(1); - break; - case 8: //UPLOAD_ERR_EXTENSION - echo "Error: File upload stopped by extension!"; - exit(1); - break; - default: - echo "Error: Unexpected value of \$_FILES['file']['error'] in upload.php!"; - exit(1); - break; - } - } - else { - echo "Error: \$_FILES is empty!

"; - echo "Possible reasons:
"; - echo "-upload_max_filesize, post_max_size or memory_limit value is too low in php.ini.
"; - echo "-file_uploads is set to Off in php.ini."; - exit(1); - } -} -?> - - \ No newline at end of file diff --git a/kastalia/upload_menu.php b/kastalia/upload_menu.php deleted file mode 100644 index 3e07018ed..000000000 --- a/kastalia/upload_menu.php +++ /dev/null @@ -1,258 +0,0 @@ - - */ - -//das absolute Kastalia directory wird als Konstante definiert -//um damit config Dateien zu includieren -@define('KASTALIA_BASE', dirname(__FILE__)); - -//die Basis von Kastalia wird includiert -//um die Anmeldung zu ueberpruefen -require_once(KASTALIA_BASE . '/lib/base.php'); -//die Konfigurationsdatei von Kastalia wird includiert -//um alle Kastalia Einstellungen in diesem Skript nutzen zu koennen -require(KASTALIA_BASE . '/config/conf.php'); -//das Menu von Kastalia wird includiert -//damit das Menu dem Benutzer angezeigt wird -require_once(KASTALIA_BASE . '/list.php'); - -echo "
Kastalia Datastore - Upload
\n"; - -//nun wird ueberprueft, ob das hochladen von Dateien ueberhaupt erlaubt ist -//falls nicht, wird eine Meldung ausgegeben und das Skript beendet -if (!$conf['upload']['uploadenabled']) { - echo "
"; - echo "File uploads are disabled!"; - exit(0); -} -?> - - - - - - - -

notice: cookies and javascripts must be enabled to upload files! | maximal upload size: - - - -

- - - - - - - -
-
-choose file: - - -
- -encrypt file?:\n"; - echo "\n"; - //dieser Teil wird nur angezeigt, wenn die checkbox zum - //verschluesselten speichern der Daten aktiviert ist - echo "
\n"; - echo "
password:\n"; - echo "\n"; - echo "\n"; - echo "
suggested password:\n"; - echo "\n"; - echo "
\n"; - } - //falls das temporaere Verzeichnis nicht beschreibbar ist, wird eine Warnmeldung ausgegeben - //und die Option Daten verschluesselt zu speichern wird ausgeblendet - else { - echo "
Warning: The option to store files encrypted is enabled by the administrator but still deactivated by Kastalia itself!
\n"; - echo "Check if the temporary directory exists and is writable.\n"; - } -} -?> - -
-
-

choose folder:

- -
-
- - -"; - echo substr($directory_element, strlen($conf['datastore']['location'])); - echo ""; - } - //die Funktion wird noch einmal aufgerufen mit dem aktuellen Ordner um zu ueberpruefen - //ob Unterordner Schreibrechte enthalten - ScanDirectory($directory_element); - } - closedir($dir_handle); - } - else { - echo "Error: Can't open directory \"$dir_name\"!"; - exit(1); - } -} - -//diese Funktion generiert ein zufaelliges Passwort mit der uebergebenden laenge -function CreateRandomPassword($passwordlength) { - //diese Zeichen koennen alle in dem Passwort vorkommen (beliebig veraenderbar) - $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-#*!$%="; - $password = ''; - for($i=0;$i<$passwordlength;$i++) { - $randomnumber = mt_rand() % strlen($chars); - $password = $password . substr($chars, $randomnumber, 1); - } - return $password; -} -?> - - \ No newline at end of file diff --git a/news/add.php b/news/add.php deleted file mode 100644 index 8f39d818c..000000000 --- a/news/add.php +++ /dev/null @@ -1,605 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -/** - * This routine removes all attributes from a given tag except - * the attributes specified in the array $attr. - * Author daneel@neezine.net 22-Aug-2005 05:08 - * http://www.php.net/manual/en/function.strip-tags.php - * - * @param string $msg text to clean - * @param string $tag tag to clean - * @param string $attr attributest to leave - * - * @return string $msg cleaned text - */ -function stripeentag($msg, $tag, $attr = array()) -{ - $lengthfirst = 0; - while (strstr(substr($msg, $lengthfirst), "<$tag ") != "") - { - $imgstart = $lengthfirst + strpos(substr($msg,$lengthfirst), "<$tag "); - $partafterwith = substr($msg, $imgstart); - $img = substr($partafterwith, 0, strpos($partafterwith, ">") + 1); - $img = str_replace(" =", "=", $msg); - $out = "<$tag"; - - for ($i=0; $i <= (count($attr) - 1); $i++) { - $long_val = strpos($img, " ", strpos($img, $attr[$i] . "=")) - (strpos($img, $attr[$i] . "=") + strlen($attr[$i]) + 1); - $val = substr($img, strpos($img, $attr[$i] . "=") + strlen($attr[$i]) + 1, $long_val); - if (strlen($val)>0) { - $attr[$i] = " ".$attr[$i]."=".$val; - } else { - $attr[$i] = ""; - } - $out .= $attr[$i]; - } - - $out .= ">"; - $partafter = substr($partafterwith, strpos($partafterwith, ">") + 1); - $msg = substr($msg, 0, $imgstart) . $out . $partafter; - $lengthfirst = $imgstart + 3; - } - - return $msg; -} - -/** - * Max upload size msg - */ -function _max_upload_size() -{ - static $msg; - - if ($msg) { - return $msg; - } - - $filesize = ini_get('upload_max_filesize'); - if (substr($filesize, -1) == 'M') { - $filesize = $filesize * 1048576; - } - $filesize = News::format_filesize($filesize); - - $postsize = ini_get('post_max_size'); - if (substr($postsize, -1) == 'M') { - $postsize = $postsize * 1048576; - } - $postsize = News::format_filesize($postsize); - - $msg = sprintf(_("Maximum file size: %s; with a total of: %s"), - $filesize, $postsize); - - return $msg; -} - -// Is logged it? -if (!$registry->isAuthenticated()) { - $notification->push(_("Only authenticated users can post news."), 'horde.warning'); - $registry->authenticateFailure('news'); -} - -// Default vars -$title = _("Add news"); -$default_lang = News::getLang(); -$id = Horde_Util::getFormData('id', false); -$return = Horde_Util::getFormData('return', false); - -// We just delete default image? -if ($id && Horde_Util::getFormData('submitbutton') == _("Delete existing picture")) { - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET picture = ? WHERE id = ?', array(0, $id)); - if ($sources instanceof PEAR_Error) { - $notification->push($sources); - } else { - News::deleteImage($id); - News::getUrlFor('news', $id)->redirect(); - } -} - -// Prepare form -$vars = Horde_Variables::getDefaultVariables(); -$form = new Horde_Form($vars, '', 'addnews'); -$form->addHidden('', 'return', 'text', false, true); - -if ($id) { - $form->setButtons(array(_("Update"), _("Delete existing picture")), _("Reset")); -} else { - $form->setButtons(array(_("Save")), _("Reset")); -} - -// General -$form->setSection('content', _("Content"), '', false); -$form->addVariable(_("News content"), 'content', 'header', false); - -$v = &$form->addVariable(_("Publish"), 'publish', 'datetime', true, false, false, News::datetimeParams()); -$v->setDefault(date('Y-m-d H:i:s')); -$form->addVariable(_("Primary category"), 'category1', 'enum', true, false, false, array($news_cat->getEnum(), _("-- select --"))); - -// Sources -$sources = $GLOBALS['news']->getSources(); -if ($sources instanceof PEAR_Error) { - $notification->push($sources); -} elseif (!empty($sources)) { - $form->addVariable(_("Source"), 'source', 'enum', false, false, false, array($sources, _("-- select --"))); -} -$form->addVariable(_("Source link"), 'sourcelink', 'text', false, false); - -// Languages -foreach ($conf['attributes']['languages'] as $key) { - $flag = (count($conf['attributes']['languages']) > 1) ? News::getFlag($key) . ' ' : ''; - $form->addVariable($flag . _("Title"), "title_$key", 'text', ($key == $default_lang) ? true : false); - if ($conf['attributes']['tags']) { - $form->addVariable($flag . _("Tags"), "tags_$key", 'text', false, false, _("Enter one or more keywords that describe your news. Separate them by spaces.")); - } - $form->addVariable($flag . _("Content"), "content_$key", 'longtext', ($key == $default_lang) ? true : false , false, false, array(20, 120)); -} - -// Additional -$form->setSection('attributes', _("Attributes"), '', true); -$form->addVariable(_("Additional news attributes"), 'attributes', 'header', false); -$form->addVariable(_("Secondary category"), 'category2', 'enum', false, false, false, array($news_cat->getEnum(), _("-- select --"))); -$form->addVariable(_("Sort order"), 'sortorder', 'enum', false, false, false, array(range(0, 10))); -$form->addVariable(_("Parents"), 'parents', 'intList', false, false, _("Enter news ids separated by commas.")); - -if ($registry->hasMethod('forums/doComments')) { - $form->addVariable(sprintf(_("Threads in %s"), $registry->get('name', 'agora')), 'threads', 'intList', false, false, _("Enter threads separated by commas.")); -} - -$form->setSection('images', _("Images"), '', true); -$form->addVariable(_("News images"), 'content', 'header', false); -$form->addVariable(_max_upload_size(), 'description', 'description', false); - -$form->addVariable(_("Picture"), 'picture_0', 'image', false, false, false, array(false)); - -foreach ($conf['attributes']['languages'] as $key) { - $flag = (count($conf['attributes']['languages']) > 1) ? News::getFlag($key) . ' ' : ''; - $form->addVariable($flag . _("Picture comment"), "caption_0_$key", 'text', false); -} - -// Link to a gallery -if ($conf['attributes']['ansel-images'] - && $registry->hasMethod('images/listGalleries') - && $registry->images->countGalleries() > 0) { - - $form->addVariable(_("Enter gallery ID or upload images below"), 'description', 'description', false); - - if ($registry->images->countGalleries() > 50) { - $form->addVariable(_("Gallery"), 'gallery', 'int', false, false); - } else { - $ansel_galleries = $registry->images->listGalleries(); - $galleries = array(); - foreach ($ansel_galleries as $gallery_id => $gallery) { - $galleries[$gallery_id] = $gallery['attribute_name']; - } - $form->addVariable(_("Gallery"), 'gallery', 'enum', false, false, false, array($galleries, true)); - } -} - -if ($registry->hasMethod('images/listGalleries')) { - $images = 4; -} - -if ($images > 1) { - $form->addVariable(_("Images will be added to a gallery linked with this article. You can edit and manage images in gallery."), 'description', 'description', false); - for ($i = 1; $i < $images; $i++) { - $form->addVariable(_("Picture") . ' ' . $i, 'picture_' . $i, 'image', false, false, false, array(false)); - $form->addVariable(_("Caption") . ' ' . $i, 'caption_' . $i, 'text', false); - } -} - -if ($conf['attributes']['attachments']) { - $form->setSection('files', _("Files"), '', true); - - $form->addVariable(_max_upload_size(), 'description', 'description', false); - - foreach ($conf['attributes']['languages'] as $key) { - $flag = (count($conf['attributes']['languages']) > 1) ? News::getFlag($key) . ' ' : ''; - for ($i = 1; $i < 6; $i++) { - $form->addVariable($flag . ' ' . _("File") . ' ' . $i, 'file_' . $key . '_' . $i, 'file', false); - } - } -} - -if ($registry->isAdmin(array('permission' => 'news:admin'))) { - $form->setSection('admin', _("Admin"), '', true); - $form->addVariable(_("News administrator settings"), 'content', 'header', false); - - if ($conf['attributes']['sponsored']) { - $form->addVariable(_("Sponsored"), 'sponsored', 'boolean', false); - } - - // Allow commeting this content - if ($conf['comments']['allow'] != 'never' && $registry->hasMethod('forums/doComments')) { - $form->addVariable(_("Disallow comments"), 'disable_comments', 'boolean', false, false); - } - - // Link to selling - $apis = array(); - foreach ($registry->listAPIs() as $api) { - if ($registry->hasMethod($api . '/getSellingForm')) { - $apis[$api] = array(); - try { - $articles = $registry->call($api . '/listCostObjects'); - if (!empty($articles)) { - foreach ($articles[0]['objects'] as $item) { - $apis[$api][$item['id']] = $item['name']; - } - } - } catch (Horde_Exception $e) { - $notification->push($e); - } - } - } - - if (!empty($apis)) { - $v = &$form->addVariable(_("Selling item"), 'selling', 'mlenum', false, false, false, array($apis)); - } - - // Show from - if ($registry->hasMethod('forms/getForms')) { - $available = $registry->call('forms/getForms'); - if ($available instanceof PEAR_Error) { - $notification->push($available, 'horde.warning'); - $available = array(); - } - $forms = array(); - foreach ($available as $f) { - $forms[$f['form_id']] = $f['form_name']; - } - - $form->addVariable(_("Form ID"), 'form_id', 'enum', false, false, false, array($forms, true)); - $form->addVariable(_("Form to"), 'form_ttl', 'datetime', false); - } -} - -// Process form -if ($form->validate()) { - - $status_inserted = false; - $allowed_cats = $news_cat->getAllowed(Horde_Perms::DELETE); - $form->getInfo(null, $info); - - // Check permissions - $info['status'] = News::UNCONFIRMED; - $info['editor'] = ''; - $info['category1'] = (int)$info['category1']; - $info['category2'] = (int)@$info['category2']; - - if (!empty($allowed_cats) && - (in_array($info['category1'], $allowed_cats) || in_array($info['category2'], $allowed_cats))) { - $info['editor'] = $GLOBALS['registry']->getAuth(); - $info['status'] = News::CONFIRMED; - } - - // Multi language - $info['chars'] = strlen(preg_replace('/\s\s+/', '', trim(strip_tags($info["content_$default_lang"])))); - - foreach ($conf['attributes']['languages'] as $key) { - if (!$info["title_$key"]) { - continue; - } - $info['body'][$key]['title'] = $info["title_$key"]; - $info['body'][$key]['content'] = $info["content_$key"]; - $info['body'][$key]['caption'] = empty($info["caption_0_$key"]) ? '' : $info["caption_0_$key"]; - $info['body'][$key]['tags'] = $conf['attributes']['tags'] ? $info["tags_$key"] : ''; - unset($info["title_$key"]); - unset($info["content_$key"]); - unset($info["caption_$key"]); - unset($info["tags_$key"]); - - if (strpos($info['body'][$key]['content'], '<') === FALSE) { - $info['body'][$key]['content'] = nl2br(trim($info['body'][$key]['content'])); - } else { - $info['body'][$key]['content'] = trim(stripeentag($info['body'][$key]['content'], 'p')); - $info['body'][$key]['content'] = trim(stripeentag($info['body'][$key]['content'], 'font')); - } - $info['chars'] = strlen(strip_tags($info['body'][$key]['content'])); - } - - // Selling - if (empty($info['selling'][1])) { - $info['selling'] = ''; - } else { - $info['selling'] = $info['selling'][1] . '|' . $info['selling'][2]; - } - - // Clean up parents ID - if ($info['parents']) { - $info['parents'] = explode(',', trim($info['parents'])); - foreach ($info['parents'] as $i => $parent_id) { - if (intval($parent_id) == 0) { - unset($info['parents'][$i]); - } - } - $info['parents'] = implode(',', array_unique($info['parents'])); - } - - // Save as current version - if (empty($id)) { - - $id = $news->write_db->nextID($news->prefix); - if ($id instanceof PEAR_Error) { - $notification->push($id); - Horde::url('browse.php')->redirect(); - } - - $query = 'INSERT INTO ' . $news->prefix - . ' (sortorder, status, publish, submitted, updated, user, editor, sourcelink, source,' - . ' sponsored, parents, category1, category2, chars, attachments, gallery, selling,' - . ' threads, form_id, form_ttl) ' - . ' VALUES (?, ?, ?, NOW(), NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - - $data = array($info['sortorder'], - $info['status'], - $info['publish'], - $GLOBALS['registry']->getAuth(), - $info['editor'], - @$info['sourcelink'], - isset($info['source']) ? $info['source'] : '', - empty($info['sponsored']) ? 0 : 1, - $info['parents'], - $info['category1'], - $info['category2'], - $info['chars'], - sizeof(@$info['attachments']), - empty($info['gallery']) ? 0 : $info['gallery'], - $info['selling'], - $info['threads'], - empty($info['form_id']) ? 0 : (int)$info['form_id'], - empty($info['form_ttl']) ? 0 : (int)$info['form_ttl']); - - $status_inserted = true; - - } else { - - $query = 'UPDATE ' . $news->prefix . ' SET ' - . 'sortorder = ?, publish = ?, updated = NOW(), editor = ?, sourcelink = ?, source = ?, ' - . 'sponsored = ?, parents = ?, category1 = ?, category2 = ?, ' - . 'chars = ?, attachments = ?, gallery = ?, selling = ?, threads = ?, ' - . 'form_id = ?, form_ttl = ? WHERE id = ?'; - - $data = array($info['sortorder'], - $info['publish'], - $info['editor'], - @$info['sourcelink'], - isset($info['source']) ? $info['source'] : '', - empty($info['sponsored']) ? 0 : 1, - $info['parents'], - $info['category1'], - $info['category2'], - $info['chars'], - sizeof(@$info['attachments']), - empty($info['gallery']) ? 0 : $info['gallery'], - $info['selling'], - $info['threads'], - empty($info['form_id']) ? 0 : (int)$info['form_id'], - empty($info['form_ttl']) ? 0 : (int)$info['form_ttl'], - $id); - } - - $result = $news->write_db->query($query, $data); - if ($result instanceof PEAR_Error) { - $notification->push($result->getDebugInfo(), 'horde.error'); - Horde::url('edit.php')->redirect(); - } - - // Picture - $images_uploaded = array(); - if (isset($info['picture_0']['uploaded'])) { - if ($info['picture_0']['uploaded'] instanceof PEAR_Error) { - if ($info['picture_0']['uploaded']->getCode() != UPLOAD_ERR_NO_FILE) { - $notification->push($info['picture_0']['uploaded']->getMessage(), 'horde.warning'); - } - } else { - $images_uploaded[] = 0; - $result = News::saveImage($id, $info['picture_0']['file']); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } else { - $news->write_db->query('UPDATE ' . $news->prefix . ' SET picture = ? WHERE id = ?', array(1, $id)); - } - } - } - - for ($i = 1; $i < $images; $i++) { - if (isset($info['picture_' . $i]['uploaded'])) { - if ($info['picture_' . $i]['uploaded'] instanceof PEAR_Error) { - if ($uploaded->getCode() != UPLOAD_ERR_NO_FILE) { - $notification->push($uploaded->getMessage(), 'horde.warning'); - } - } else { - $images_uploaded[] = $i; - } - } - } - - // Don't create a galler if no picture or only default one was uploaded - if (!empty($images_uploaded) && - !(count($images_uploaded) == 1 && $images_uploaded[0] == 0)) { - - // Do we have a gallery? - if (empty($info['gallery'])) { - $abbr = Horde_String::substr(strip_tags($info['body'][$default_lang]['content']), 0, $conf['preview']['list_content']); - try { - $result = $registry->images->createGallery(null, - array('name' => $info['body'][$default_lang]['title'], - 'desc' => $abbr)); - $info['gallery'] = $result; - } catch (Horde_Exception $e) { - $notification->push(_("There was an error creating gallery: ") . $e->getMessage(), 'horde.warning'); - } - } - - if (!empty($info['gallery'])) { - $news->write_db->query('UPDATE ' . $news->prefix . ' SET gallery = ? WHERE id = ?', array($info['gallery'], $id)); - foreach ($images_uploaded as $i) { - try { - $registry->images->saveImage($info['gallery'], - array('filename' => $info['picture_' . $i]['file'], - 'description' => $info['caption_' . ($i == 0 ? $i . '_' . $default_lang: $i)], - 'type' => $info['picture_' . $i]['type'], - 'data' => file_get_contents($info['picture_' . $i]['file']))); - } catch (Horde_Exception $e) { - $notification->push(_("There was an error with the uploaded image: ") . $e->getMessage(), 'horde.warning'); - } - } - } - } - - // Files - if ($conf['attributes']['attachments']) { - $uploaded = false; - $form->setSection('files', _("Files"), '', true); - foreach ($conf['attributes']['languages'] as $key) { - for ($i = 1; $i < 6; $i++) { - $input = 'file_' . $key . '_' . $i; - try { - $GLOBALS['browser']->wasFileUploaded($input); - $file_id = $news->write_db->nextID($news->prefix . '_files'); - if ($file_id instanceof PEAR_Error) { - $notification->push($file_id); - } else { - $result = News::saveFile($file_id, $info[$input]['file']); - if ($result instanceof PEAR_Error) { - $notification->push($result->getMessage(), 'horde.warning'); - } else { - $result = $news->write_db->query('INSERT INTO ' . $news->prefix . '_files (file_id, news_id, news_lang, file_name, file_size, file_type) VALUES (?, ?, ?, ?, ?, ?)', - array($file_id, $id, $key, $info[$input]['name'], $info[$input]['size'], $info[$input]['type'])); - if ($result instanceof PEAR_Error) { - $notification->push($result->getMessage(), 'horde.warning'); - } - } - } - } catch (Horde_Browser_Exception $e) { - if ($e->getCode() != UPLOAD_ERR_NO_FILE) { - $notification->push($e->getMessage(), 'horde.warning'); - } - } - } - } - if ($uploaded) { - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET attachments = ? WHERE id = ?', array(1, $id)); - if ($result instanceof PEAR_Error) { - $notification->push($result->getMessage(), 'horde.warning'); - } - } - } - - // Comments - if (isset($info['disable_comments']) && $info['disable_comments']) { - $news->write_db->query('UPDATE ' . $news->prefix . ' SET comments = ? WHERE id = ?', array(-1, $id)); - } - - // Bodies - $news->write_db->query('DELETE FROM ' . $news->prefix . '_body WHERE id = ?', array($id)); - $query_body = $news->write_db->prepare('INSERT INTO ' . $news->prefix . '_body ' - . '(id, lang, title, abbreviation, content, picture_comment, tags) VALUES (?, ?, ?, ?, ?, ?, ?)'); - - foreach ($info['body'] as $lang => $values) { - $abbr = Horde_String::substr(strip_tags($values['content']), 0, $conf['preview']['list_content']); - $news->write_db->execute($query_body, array($id, $lang, $values['title'], $abbr, $values['content'], $values['caption'], $values['tags'])); - } - - // Save as future version - if ($status_inserted === true) { - $status_version = 'insert'; - } else { - $status_version = 'update'; - } - $version = $news->db->getOne('SELECT MAX(version) FROM ' . $news->prefix . '_versions WHERE id = ?', array($id)); - $result = $news->write_db->query('INSERT INTO ' . $news->prefix . '_versions (id, version, action, created, user_uid, content) VALUES (?, ?, ?, NOW(), ? ,?)', - array($id, $version + 1, $status_version, $GLOBALS['registry']->getAuth(), serialize($info['body']))); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - // Expire newscache - foreach ($conf['attributes']['languages'] as $key) { - $cache->expire('news_' . $key . '_' . $id); - } - - // Return - if ($return) { - $url = $return; - } elseif (in_array($info['category1'], $allowed_cats) || - in_array($info['category2'], $allowed_cats)) { - $url = Horde_Util::addParameter(Horde::url('edit.php'), 'id', $id); - } else { - $url = Horde::url('browse.php'); - } - - if ($info['status'] != News::CONFIRMED && $status_inserted == true) { - $notification->push(_("News added. The editors will check the entry and confirm it if they find it suitable."), 'horde.success'); - } elseif ($info['status'] == News::CONFIRMED && $status_inserted == true) { - $notification->push(_("News published."), 'horde.success'); - } elseif ($status_inserted == false) { - $notification->push(_("News updated."), 'horde.success'); - } - - $url->redirect(); - -} elseif ($id && !$form->isSubmitted()) { - - $title = _("Edit news"); - $sql = 'SELECT * FROM ' . $news->prefix . ' WHERE id = ?'; - $result = $news->db->getRow($sql, array($id), DB_FETCHMODE_ASSOC); - - foreach ($result as $key => $value) { - if ($key == 'picture') { - continue; - } elseif ($key == 'comments' && $value == -1) { - $key = 'disable_comments'; - $value = true; - } elseif ($key == 'selling') { - if (empty($value)) { - continue; - } else { - $value = explode('|', $value); - $vars->set('selling', array(1 => $value[0], 2 => $value[1])); - continue; - } - } - - $vars->set($key, $value); - } - - $sql = 'SELECT lang, title, content, picture_comment, tags FROM ' . $news->prefix . '_body WHERE id = ?'; - $result = $news->db->getAll($sql, array($id), DB_FETCHMODE_ASSOC); - foreach ($result as $row) { - $vars->set('title_' . $row['lang'], $row['title']); - $vars->set('content_' . $row['lang'], $row['content']); - $vars->set('caption_0_' . $row['lang'], $row['picture_comment']); - if ($conf['attributes']['tags']) { - $vars->set('tags_' . $row['lang'], $row['tags']); - } - } - - $form->setButtons(_("Update"), _("Reset")); -} - -// Add editor now to avoud JS error notifications no redirect -foreach ($conf['attributes']['languages'] as $key) { - $injector->getInstance('Horde_Editor')->initialize(array('id' => 'content_' . $key)); -} - -require_once NEWS_TEMPLATES . '/common-header.inc'; -require_once NEWS_TEMPLATES . '/menu.inc'; -require_once NEWS_TEMPLATES . '/add/before.inc'; - -$form->renderActive(null, null, Horde_Util::addParameter(Horde::url('add.php'), 'id', $id, false), 'post'); - -require_once $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/admin/categories/delete.php b/news/admin/categories/delete.php deleted file mode 100644 index 71bd03606..000000000 --- a/news/admin/categories/delete.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you - * did not receive this file, see http://cvs.horde.org/co.php/news/LICENSE. - * - * $Id: delete.php 183 2008-01-06 17:39:50Z duck $ - */ -define('NEWS_BASE', dirname(__FILE__) . '/../..'); -require_once NEWS_BASE . '/lib/base.php'; -require NEWS_BASE . '/admin/tabs.php'; - -$vars = Horde_Variables::getDefaultVariables(); -$form = new Horde_Form($vars, _("Do you really wont to delete this category?"), 'delete'); -$form->setButtons(array(_("Remove"), _("Cancel"))); - -$category_id = Horde_Util::getFormData('category_id'); -$form->addHidden('', 'category_id', 'int', $category_id); - -if ($form->validate()) { - if (Horde_Util::getFormData('submitbutton') == _("Remove")) { - $news_cat->deleteCategory($category_id); - if ($result instanceof PEAR_Error) { - $notification->push(_("Category was not deleted.") . ' ' . $result->getMessage(), 'horde.error'); - } else { - $notification->push(_("Category deleted."), 'horde.success'); - } - } else { - $notification->push(_("Category was not deleted."), 'horde.warning'); - } - Horde::url('admin/categories/index.php')->redirect(); -} - -require NEWS_BASE . '/templates/common-header.inc'; -require NEWS_BASE . '/templates/menu.inc'; -echo $tabs->render('categories'); -$form->renderActive(null, null, null, 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/admin/categories/edit.php b/news/admin/categories/edit.php deleted file mode 100644 index f754326a1..000000000 --- a/news/admin/categories/edit.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you - * did not receive this file, see http://cvs.horde.org/co.php/news/LICENSE. - * - * $Id: edit.php 238 2008-01-16 15:28:51Z duck $ - */ - -define('NEWS_BASE', dirname(__FILE__) . '/../..'); -require_once NEWS_BASE . '/lib/base.php'; -require NEWS_BASE . '/admin/tabs.php'; - -$category_id = Horde_Util::getFormData('category_id'); -$title = !empty($category_id) ? _("Edit category") : _("Add category"); -$vars = Horde_Variables::getDefaultVariables(); -$form = new Horde_Form($vars, $title, 'editcategory'); - -if ($category_id && !$form->isSubmitted()) { - $category = $news_cat->getCatArray($category_id); - $vars->merge($category); -} - -$form->addHidden('', 'category_id', 'int', $category_id); - -foreach ($GLOBALS['conf']['attributes']['languages'] as $lang) { - $flag = (count($conf['attributes']['languages']) > 1) ? News::getFlag($lang) . ' ' : ''; - $form->addVariable($flag . _("Name"), 'category_name_' . $lang, 'text', true); - $form->addVariable($flag . _("Description"), 'category_description_' . $lang, 'text', false); -} - -$form->addVariable(_("Parent"), 'category_parentid', 'radio', false, false, null, array($news_cat->getCategories(), true)); -$v = &$form->addVariable(_("Resize Image"), 'image_resize', 'boolean', false); -$v->setDefault(true); -$form->addVariable(_("Image"), 'image', 'image', false); - -if ($form->validate()) { - $form->getInfo(null, $info); - $result = $news_cat->saveCategory($info); - if ($result instanceof PEAR_Error) { - $notification->push($result->getMessage() . ': ' . $result->getDebugInfo(), 'horde.error'); - } else { - $notification->push(sprintf(_("Category succesfully saved."))); - Horde::url('admin/categories/index.php', true)->redirect(); - } -} - -require NEWS_BASE . '/templates/common-header.inc'; -require NEWS_BASE . '/templates/menu.inc'; -echo $tabs->render('cetegories'); -$form->renderActive(null, null, null, 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/admin/categories/index.php b/news/admin/categories/index.php deleted file mode 100644 index 3faacff44..000000000 --- a/news/admin/categories/index.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you - * did not receive this file, see http://cvs.horde.org/co.php/news/LICENSE. - * - * $Id: index.php 183 2008-01-06 17:39:50Z duck $ - */ - -define('NEWS_BASE', dirname(__FILE__) . '/../..'); -require_once NEWS_BASE . '/lib/base.php'; -require NEWS_BASE . '/admin/tabs.php'; - -// Get category list -$categories = $news_cat->getCategories(false); -if ($categories instanceof PEAR_Error) { - $notification->push($categories->getMessage(), 'horde.error'); - $categories = array(); -} - -/* Set up the template fields. */ -$title = _("Category Administration"); -$edit_url = Horde::url('admin/categories/edit.php'); -$edit_img = Horde::img('edit.png', _("Edit")); -$delete_url = Horde::url('admin/categories/delete.php'); -$delete_img = Horde::img('delete.png', _("Delete")); - -foreach ($categories as $category_id => $category) { - $categories[$category_id]['actions'][] = Horde::link(Horde_Util::addParameter($delete_url, 'category_id', $category_id), _("Delete")) . - $delete_img . '
'; - $categories[$category_id]['actions'][] = Horde::link(Horde_Util::addParameter($edit_url, 'category_id', $category_id), _("Edit")) . - $edit_img . ''; -} - -$view = new News_View(); -$view->categories = $categories; -$view->add_url = Horde::link($edit_url, _("Add New")) . _("Add New") . ''; - -Horde::addScriptFile('tables.js', 'horde'); -require NEWS_BASE . '/templates/common-header.inc'; -require NEWS_BASE . '/templates/menu.inc'; -echo $tabs->render('cetegories'); -echo $view->render('/categories/index.php'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/admin/sources/delete.php b/news/admin/sources/delete.php deleted file mode 100644 index a7a6d3b8e..000000000 --- a/news/admin/sources/delete.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you - * did not receive this file, see http://cvs.horde.org/co.php/news/LICENSE. - * - * $Id: delete.php 183 2008-01-06 17:39:50Z duck $ - */ - -define('NEWS_BASE', dirname(__FILE__) . '/../..'); -require_once NEWS_BASE . '/lib/base.php'; -require '../tabs.php'; - -$vars = Horde_Variables::getDefaultVariables(); -$form = new Horde_Form($vars, _("Do you really wont to delete this source?"), 'delete'); -$form->setButtons(array(_("Remove"), _("Cancel"))); - -$source_id = Horde_Util::getFormData('source_id'); -$form->addHidden('', 'source_id', 'int', $source_id); - -if ($form->validate()) { - if (Horde_Util::getFormData('submitbutton') == _("Remove")) { - $news->deleteSource($source_id); - if ($result instanceof PEAR_Error) { - $notification->push(_("Source was not deleted.") . ' ' . $result->getMessage(), 'horde.error'); - } else { - $notification->push(_("Source deleted."), 'horde.success'); - } - } else { - $notification->push(_("Source was not deleted."), 'horde.warning'); - } - Horde::url('admin/sources/index.php')->redirect(); -} - -require NEWS_BASE . '/templates/common-header.inc'; -require NEWS_BASE . '/templates/menu.inc'; -echo $tabs->render('sources'); -$form->renderActive(null, null, null, 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/admin/sources/edit.php b/news/admin/sources/edit.php deleted file mode 100644 index 40070a01c..000000000 --- a/news/admin/sources/edit.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you - * did not receive this file, see http://cvs.horde.org/co.php/news/LICENSE. - * - * $Id: edit.php 183 2008-01-06 17:39:50Z duck $ - */ - -define('NEWS_BASE', dirname(__FILE__) . '/../..'); -require_once NEWS_BASE . '/lib/base.php'; -require '../tabs.php'; - -$vars = Horde_Variables::getDefaultVariables(); -$source_id = $vars->get('source_id'); -$title = !empty($source_id) ? _("Edit Source") : _("Add Source"); - -$form = new Horde_Form($vars, $title, 'editsource'); -if ($source_id && !$form->isSubmitted()) { - $sources = $news->getSources(true); - foreach ($sources[$source_id] as $key => $val) { - if ($key != 'source_image') { - $vars->set($key, $val); - } - } -} - -$form->addHidden('', 'source_id', 'int', $source_id); -$form->addVariable(_("Name"), 'source_name', 'text', true); -$form->addVariable(_("Url"), 'source_url', 'text', true); - -$v = &$form->addVariable(_("Resize Image"), 'source_image_resize', 'boolean', false); -$v->setDefault(true); -$form->addVariable(_("Image"), 'source_image', 'image', false); - -if ($form->validate()) { - $form->getInfo(null, $info); - $result = $news->saveSource($info); - if ($result instanceof PEAR_Error) { - $notification->push($result->getMessage() . ': ' . $result->getDebugInfo(), 'horde.error'); - } else { - $notification->push(_("Source saved succesfully.")); - Horde::url('admin/sources/index.php')->redirect(); - } -} - -require NEWS_TEMPLATES . '/common-header.inc'; -require NEWS_TEMPLATES . '/menu.inc'; -echo $tabs->render('sources'); -$form->renderActive(null, null, null, 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/admin/sources/index.php b/news/admin/sources/index.php deleted file mode 100644 index 11ff22395..000000000 --- a/news/admin/sources/index.php +++ /dev/null @@ -1,49 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you - * did not receive this file, see http://cvs.horde.org/co.php/news/LICENSE. - * - * $Id: index.php 183 2008-01-06 17:39:50Z duck $ - */ - -define('NEWS_BASE', dirname(__FILE__) . '/../..'); -require_once NEWS_BASE . '/lib/base.php'; -require '../tabs.php'; - -$title = _("Sources Administration"); -$sources = $news->getSources(true); -if ($sources instanceof PEAR_Error) { - $notification->push($sources->getDebugInfo(), 'horde.error'); - $sources = array(); -} - -$edit_url = Horde::url('admin/sources/edit.php'); -$edit_img = Horde::img('edit.png', _("Edit")); -$delete_url = Horde::url('admin/sources/delete.php'); -$delete_img = Horde::img('delete.png', _("Delete")); -$view_url = Horde::url('browse.php'); -$view_img = Horde::img('category.png', _("View items")); - -foreach ($sources as $source_id => $source) { - $sources[$source_id]['actions'][] = Horde::link(Horde_Util::addParameter($view_url, 'source_id', $source_id), _("View articles")) . - $view_img . ''; - $sources[$source_id]['actions'][] = Horde::link(Horde_Util::addParameter($delete_url, 'source_id', $source_id), _("Delete")) . - $delete_img . ''; - $sources[$source_id]['actions'][] = Horde::link(Horde_Util::addParameter($edit_url, 'source_id', $source_id), _("Edit")) . - $edit_img . ''; -} - -$view = new News_View(); -$view->sources = $sources; -$view->add_url = Horde::link($edit_url, _("Add New")) . _("Add New") . ''; - -Horde::addScriptFile('tables.js', 'horde'); -require NEWS_BASE . '/templates/common-header.inc'; -require NEWS_BASE . '/templates/menu.inc'; -echo $tabs->render('sources'); -echo $view->render('/sources/index.php'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/admin/tabs.php b/news/admin/tabs.php deleted file mode 100644 index 6e0f6a691..000000000 --- a/news/admin/tabs.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ - -/* Only admin should be using this. */ -if (!$registry->isAdmin(array('permission' => 'news:admin'))) { - $notification->push(_("You are not authorised for this action."), 'horde.warning'); - $registry->authenticateFailure('news'); -} - -$vars = Horde_Variables::getDefaultVariables(); -$tabs = new Horde_Core_Ui_Tabs('admin', $vars); - -$tabs->addTab(_("Sources"), Horde::url('admin/sources/index.php'), 'sources'); -$tabs->addTab(_("Categories"), Horde::url('admin/categories/index.php'), 'categories'); diff --git a/news/browse.php b/news/browse.php deleted file mode 100644 index c634762a4..000000000 --- a/news/browse.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -// Default vars -$title = _("Browse"); -$page = Horde_Util::getGet('news_page', 0); -$per_page = $prefs->getValue('per_page'); -$browse_url = Horde::url('browse.php'); -$cid = Horde_Util::getGet('cid'); - -// Define creteria -if (!empty($_GET)) { - $criteria = $_GET; - $browse_url = Horde_Util::addParameter($browse_url, $_GET); -} else { - $criteria = array(); -} - -// Count rows -$count = $news->countNews($criteria); -if ($count instanceof PEAR_Error) { - echo $count->getMessage() . ': ' . $count->getDebugInfo(); - exit; -} - -// Get news -$rows = $news->listNews($criteria, $page*$per_page, $per_page); -if ($rows instanceof PEAR_Error) { - echo $rows->getMessage() . ': ' . $rows->getDebugInfo(); - exit; -} - -// If we have only one row redirect ot it -if ($count == 1 && sizeof($cats) < 2 && $page < 1) { - News::getUrlFor('news', $rows[0]['id'])->redirect(); -} - -// Get pager -$pager = News_Search::getPager(array(), $count, $browse_url); - -require_once NEWS_TEMPLATES . '/common-header.inc'; -require_once NEWS_TEMPLATES . '/menu.inc'; - -$browse_template_path = News::getTemplatePath($cid, 'browse'); -require_once $browse_template_path . 'header.inc'; -foreach ($rows as $row) { - require $browse_template_path . 'row.inc'; -} -require_once $browse_template_path . '/footer.inc'; - -require_once $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/cloud.php b/news/cloud.php deleted file mode 100644 index 637062dfd..000000000 --- a/news/cloud.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$cloud = $news->getCloud(); -if ($cloud instanceof PEAR_Error) { - $notification->push($cloud); - $cloud = ''; -} - -require NEWS_TEMPLATES . '/common-header.inc'; -require NEWS_TEMPLATES . '/menu.inc'; - -echo $cloud; - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/config/conf.xml b/news/config/conf.xml deleted file mode 100644 index 5736deb54..000000000 --- a/news/config/conf.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - These are the settings for storing all the News data, such as categories, - items within those categories, item options, etc. - - sql - - - - - horde_datatree - horde_datatree_attributes - - - - - - - - - - - Settings for displaying - 130 - - - - Enable optional news attributes - TRUE - TRUE - false - true - - - - - - - - - Images settings - true - horde - - horde_vfs - - - /schedul-images - png - - jpeg - png - - - 150 - 150 - 300 - 300 - - - - Comments - authenticated - - authenticated - never - all - - - - - - - - - - Trackback Settings - 1 - 30 - 30 - - - Wordlist - Regex - DNSBL - SURBL - - - - - - - - Menu Settings - - - - - - - - - - - diff --git a/news/config/prefs.php.dist b/news/config/prefs.php.dist deleted file mode 100644 index 8afaa03f7..000000000 --- a/news/config/prefs.php.dist +++ /dev/null @@ -1,51 +0,0 @@ - _("Preview"), - 'label' => _("How to preview news"), - 'desc' => _("Set news previerw paramaters"), - 'members' => array('per_page', 'sort_by', 'sort_dir') -); - -$_prefs['per_page'] = array( - 'value' => 20, - 'locked' => false, - 'shared' => true, - 'type' => 'number', - 'desc' => _("How many news to show per page") -); - -$_prefs['sort_by'] = array( - 'value' => 'n.publish', - 'locked' => false, - 'shared' => true, - 'type' => 'enum', - 'enum' => array('n.publish' => _("Publish date"), - 'n.id' => _("Id"), - 'nl.title' => _("Title")), - 'desc' => _("Sort news by") -); - -$_prefs['sort_dir'] = array( - 'value' => 'DESC', - 'locked' => false, - 'shared' => true, - 'type' => 'enum', - 'enum' => array('DESC' => _("Descesending"), - 'ASC' => _("Ascesending")), - 'desc' => _("Sort news by") -); - -// the layout of the news portal. -$_prefs['news_layout'] = array( - 'value' => 'a:0:{}', - 'locked' => false, - 'shared' => false, - 'type' => 'implicit' -); - diff --git a/news/content.php b/news/content.php deleted file mode 100644 index 6e4b34b3f..000000000 --- a/news/content.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -// Default layout. -$layout = new Horde_Block_Layout_View( - unserialize($prefs->getValue('news_layout')), - Horde::url('content_edit.php'), - Horde::url('content.php')); - -$layout_html = $layout->toHtml(); -$title = $registry->get('name'); -require NEWS_TEMPLATES . '/common-header.inc'; -require NEWS_TEMPLATES . '/menu.inc'; -echo '
 
'; -echo $layout_html; -require $registry->get('templates', 'horde') . '/common-footer.inc'; \ No newline at end of file diff --git a/news/content_edit.php b/news/content_edit.php deleted file mode 100644 index a1a8f6773..000000000 --- a/news/content_edit.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -// Instantiate the blocks objects. -$blocks = &Horde_Block_Collection::singleton(array('news')); -$layout = &Horde_Block_Layout_Manager::singleton('news_layout', $blocks, unserialize($prefs->getValue('news_layout'))); - -// Handle requested actions. -$layout->handle(Horde_Util::getFormData('action'), - (int)Horde_Util::getFormData('row'), - (int)Horde_Util::getFormData('col')); -if ($layout->updated()) { - $prefs->setValue('news_layout', $layout->serialize()); -} - -$title = sprintf(_("%s :: Add Content"), $registry->get('name')); -require NEWS_TEMPLATES . '/common-header.inc'; -require NEWS_TEMPLATES . '/menu.inc'; -$notification->notify(array('listeners' => 'status')); -require $registry->get('templates', 'horde') . '/portal/edit.inc'; -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/delete.php b/news/delete.php deleted file mode 100644 index de1013536..000000000 --- a/news/delete.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -if (!$registry->isAdmin(array('permission' => 'news:admin'))) { - $notification->push(_("Only admin can delete a news.")); - Horde::url('edit.php')->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$form = new Horde_Form($vars, _("Are you sure you want to delete this news?"), 'delete'); -$form->setButtons(array(_("Remove"), _("Cancel"))); - -$id = (int)Horde_Util::getFormData('id'); -$form->addHidden('', 'id', 'int', $id); - -$row = $news->get($id); -$form->addVariable($row['title'], 'news', 'description', true); -$form->addVariable($row['content'], 'content', 'description', true); - -if ($form->validate()) { - - if (Horde_Util::getFormData('submitbutton') == _("Remove")) { - - // Delete attachment - $sql = 'SELECT file_id FROM ' . $news->prefix . '_files WHERE news_id = ?'; - $files = $news->db->getCol($sql, 0, array($id)); - foreach ($files as $file) { - $result = News::deleteFile($file_id); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - } - - // Delete image and gallery - $sql = 'SELECT picture, gallery FROM ' . $news->prefix . ' WHERE id = ?'; - $image = $news->db->getRow($sql, array($id), DB_FETCHMODE_ASSOC); - if ($image['picture']) { - $result = News::deleteImage($id); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - } - if ($image['gallery']) { - try { - $registry->call('images/removeGallery', array(null, $image['gallery'])); - } catch (Horde_Exception $e) { - $notification->push($e); - } - } - - // Delete from DB - $news->write_db->query('DELETE FROM ' . $news->prefix . ' WHERE id = ?', array($id)); - $news->write_db->query('DELETE FROM ' . $news->prefix . '_version WHERE id = ?', array($id)); - $news->write_db->query('DELETE FROM ' . $news->prefix . '_body WHERE id = ?', array($id)); - $news->write_db->query('DELETE FROM ' . $news->prefix . '_user_reads WHERE id = ?', array($id)); - $news->write_db->query('DELETE FROM ' . $news->prefix . '_files WHERE id = ?', array($id)); - - // Delete forum - if ($registry->hasMethod('forums/deleteForum')) { - try { - $registry->call('forums/deleteForum', array('news', $id)); - } catch (Horde_Exception $e) { - $notification->push($e); - } - } - - $notification->push(sprintf(_("News %s: %s"), $id, _("deleted")), 'horde.success'); - - } else { - - $notification->push(sprintf(_("News %s: %s"), $id, _("not deleted")), 'horde.warning'); - } - - Horde::url('edit.php')->redirect(); -} - -require NEWS_TEMPLATES . '/common-header.inc'; -require NEWS_TEMPLATES . '/menu.inc'; -$form->renderActive(null, null, null, 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/delete_file.php b/news/delete_file.php deleted file mode 100644 index 0ec4fe15f..000000000 --- a/news/delete_file.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -if (!$registry->isAdmin(array('permission' => 'news:admin'))) { - $notification->push(_("Only admin can delete a news.")); - Horde::url('edit.php')->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$form = new Horde_Form($vars, _("Are you sure you want to delete file?"), 'delete'); -$form->setButtons(array(_("Remove"), _("Cancel"))); - -$news_id = (int)Horde_Util::getFormData('news_id'); -$form->addHidden('', 'news_id', 'int', true); - -$news_lang = Horde_Util::getFormData('lang', News::getLang()); -$form->addHidden('', 'news_lang', 'text', false); - -$file_id = Horde_Util::getFormData('file_id'); -$form->addHidden('', 'file_id', 'text', true); - -$article = $news->get($news_id); -$files = $news->getFiles($news_id); -foreach ($files as $file) { - if ($file['file_id'] == $file_id) { - break; - } -} - -$form->addVariable($file['file_name'], 'file_name', 'description', false); -$form->addVariable(News::format_filesize($file['file_size']), 'file_size', 'description', false); -$form->addVariable($article['title'], 'news', 'description', false); -$form->addVariable($article['content'], 'content', 'description', false); - -if ($form->validate()) { - - if (Horde_Util::getFormData('submitbutton') == _("Remove")) { - $result = News::deleteFile($file_id); - if ($result instanceof PEAR_Error) { - - $notification->push(sprintf(_("Error deleteing file \"%s\" from news \"%s\""), $file_id['file_name'], $article['title']), 'horde.success'); - - } else { - - $result = $news->write_db->query('DELETE FROM ' . $news->prefix . '_files WHERE file_id = ?', array($file_id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $count = $news->db->getOne('SELECT COUNT(*) FROM ' . $news->prefix . '_files WHERE news_id = ?', array($news_id)); - if ($count instanceof PEAR_Error) { - $notification->push($count); - } - - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET attachments = ? WHERE id = ?', array($count, $news_id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $notification->push(sprintf(_("File \"%s\" was deleted from news \"%s\""), $file_id['file_name'], $article['title']), 'horde.success'); - - $cache->expire('news_' . $news_lang . '_' . $news_id); - } - - } else { - - $notification->push(sprintf(_("File \"%s\" was not deleted from news \"%s\""), $file_id['file_name'], $article['title']), 'horde.success'); - - } - - News::getUrlFor('news', $news_id)->redirect(); -} - -require NEWS_TEMPLATES . '/common-header.inc'; -require NEWS_TEMPLATES . '/menu.inc'; -$form->renderActive(null, null, null, 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/diff.php b/news/diff.php deleted file mode 100644 index 4930ee0f4..000000000 --- a/news/diff.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$title = _("Diff"); -$id = Horde_Util::getFormData('id', 0); -$version = Horde_Util::getFormData('version', 0); - -/* Set up the diff renderer. */ -$render_type = Horde_Util::getFormData('render', 'inline'); -$class = 'Text_Diff_Renderer_' . $render_type; -$renderer = new $class(); - -/* get current version content */ -$current_data = array(); -$result = $news->db->getAll('SELECT lang, title, content FROM ' . $news->prefix . '_body WHERE id = ?', array($id), DB_FETCHMODE_ASSOC); -if ($result instanceof PEAR_Error) { - var_dump($result); - exit; -} - -foreach ($result as $row) { - $current_data[$row['lang']]['title'] = $row['title']; - $current_data[$row['lang']]['content'] = $row['content']; -} - -/* get version data */ -$version_data = $news->db->getOne('SELECT content FROM ' . $news->prefix . '_versions WHERE id = ? AND version = ?', array($id, $version)); -if ($version_data instanceof PEAR_Error) { - var_dump($version_data); - exit; -} - -$version_data = unserialize($version_data); - -Horde_Themes::includeStylesheetFiles(); - -while (list($k, $v) = each($current_data)) { - echo '
' . $nls['languages'][$k] . '
' . "\n"; - $to = explode("\n", @htmlentities(strip_tags($v['content']))); - $from = explode("\n", @htmlentities(strip_tags($version_data[$k]['content']))); - $diff = new Text_Diff($from, $to); - if (!empty($diff)) { - echo nl2br($renderer->render($diff)); - } else { - return _("No change."); - } -} diff --git a/news/edit.php b/news/edit.php deleted file mode 100644 index aab432bb0..000000000 --- a/news/edit.php +++ /dev/null @@ -1,205 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -// redirect if not an admin -$allowed_cats = $news_cat->getAllowed(Horde_Perms::DELETE); -if (empty($allowed_cats)) { - $notification->push(_("You have not editor permission on any category.")); - Horde::url('add.php')->redirect(); -} - -$id = (int)Horde_Util::getFormData('id', 0); -$page = (int)Horde_Util::getFormData('page', 0); -$browse_url = Horde_Util::addParameter(Horde::url('edit.php'), array('page' => $page, 'id' => $id), null, false); -$edit_url = Horde::url('add.php'); -$read_url = Horde::url('reads.php'); -$has_comments = $registry->hasMethod('forums/doComments'); -$actionID = Horde_Util::getFormData('actionID'); - -// save as future version -if (!empty($actionID) && $id > 0) { - $version = $news->db->getOne('SELECT MAX(version) FROM ' . $news->prefix . '_versions WHERE id = ?', array($id)); - $result = $news->write_db->query('INSERT INTO ' . $news->prefix . '_versions (id, version, action, created, user_uid) VALUES (?,?,?,NOW(),?)', - array($id, $version + 1, $actionID, $GLOBALS['registry']->getAuth())); -} - -if ($id) { - $article = $news->get($id); -} - -switch ($actionID) { -case 'deletepicture'; - - $result = News::deleteImage($id); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET picture = ? WHERE id = ?', array(0, $id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } else { - $notification->push(sprintf(_("News \"%s\" (%s): %s"), $article['title'], $id, _("picture deleted")), 'horde.success'); - } - - $browse_url->redirect(); - -break; - -case 'deactivate'; - - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET status = ? WHERE id = ?', array(News::UNCONFIRMED, $id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $notification->push(sprintf(_("News \"%s\" (%s): %s"), $article['title'], $id, _("deactivated")), 'horde.success'); - $browse_url->redirect(); - -break; -case 'activate'; - - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET status = ? WHERE id = ?', array(News::CONFIRMED, $id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $notification->push(sprintf(_("News \"%s\" (%s): %s"), $article['title'], $id, _("activated")), 'horde.success'); - $browse_url->redirect(); - -break; -case 'lock'; - - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET status = ? WHERE id = ?', array(News::LOCKED, $id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $notification->push(sprintf(_("News \"%s\" (%s): %s"), $article['title'], $id, _("locked")), 'horde.success'); - $browse_url->redirect(); - -break; -case 'unlock'; - - $result = $news->write_db->query('UPDATE ' . $news->prefix . ' SET status = ? WHERE id = ?', array(News::UNCONFIRMED, $id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $notification->push(sprintf(_("News \"%s\" (%s): %s"), $article['title'], $id, _("unlocked")), 'horde.success'); - $browse_url->redirect(); - - -break; -case 'renew'; - - $version = Horde_Util::getFormData('version'); - - $version_data = $news->db->getRow('SELECT content FROM ' . $news->prefix . '_versions WHERE id = ? AND version = ?', - array($id, $version), DB_FETCHMODE_ASSOC); - if ($version_data instanceof PEAR_Error) { - $notification->push($version_data); - } - - $version_data['content'] = unserialize($version_data['content']); - $result = $news->write_db->query('DELETE FROM ' . $news->prefix . '_body WHERE id = ?', array($id)); - if ($result instanceof PEAR_Error) { - $notification->push($result); - } - - $new_version = array(); - $sql = 'INSERT INTO ' . $news->prefix . '_body (id,lang,title,abbreviation,content) VALUES (?,?,?,?,?)'; - - foreach ($version_data['content'] as $lang => $values) { - $new_version[$lang] = $values; - $data = array($id, - $lang, - $values['title'], - substr(strip_tags($values['content']), 0, $conf['preview']['list_content']), - $values['content']); - $news->write_db->query($sql, $data); - } - - /* save as future version */ - $version = $news->db->getOne('SELECT MAX(version) FROM ' . $news->prefix . '_versions WHERE id = ?', array($id)) + 1; - $result = $news->write_db->query('INSERT INTO ' . $news->prefix . '_versions (id, version, created, user_uid, content) VALUES (?,?,NOW(),?,?)', - array($id, $version, $GLOBALS['registry']->getAuth(), serialize($new_version))); - - $notification->push(sprintf(_("News \"%s\" (%s): %s"), $article['title'], $id, _("renewed")), 'horde.success'); - $browse_url->redirect(); -} - -$title = _("Edit"); -$vars = Horde_Variables::getDefaultVariables(); -$form = new News_Search($vars); -$form->getInfo(null, $info); - -/* prepare query */ -$binds = $news->buildQuery(Horde_Perms::DELETE, $info); -$sql = 'SELECT n.id, n.sortorder, n.category1, n.category2, n.source, n.status, n.editor, n.publish, ' . - 'n.user, n.comments, n.unpublish, n.picture, n.chars, n.view_count, n.attachments, l.title, n.selling ' - . $binds[0]; - -if (!isset($info['sort_by'])) { - $info['sort_by'] = 'n.publish'; -} -if (!isset($info['sort_dir'])) { - $info['sort_dir'] = 'DESC'; -} - -$sql .= ' ORDER BY ' . $info['sort_by'] . ' ' . $info['sort_dir']; - -// Count rows -$count = $news->countNews($info, Horde_Perms::DELETE); -if ($count instanceof PEAR_Error) { - echo $count->getMessage() . ': ' . $count->getDebugInfo(); - exit; -} - -// Select rows -$page = Horde_Util::getGet('news_page', 0); -$per_page = $prefs->getValue('per_page'); -$sql = $news->db->modifyLimitQuery($sql, $page*$per_page, $per_page); -$rows = $news->db->getAll($sql, $binds[1], DB_FETCHMODE_ASSOC); -if ($rows instanceof PEAR_Error) { - echo $rows->getMessage() . ': ' . $rows->getDebugInfo(); - exit; -} - -// Get pager -$pager = News_Search::getPager($binds[1], $count, $browse_url); - -// Output -Horde::addScriptFile('tables.js', 'horde'); - -require_once NEWS_TEMPLATES . '/common-header.inc'; -require_once NEWS_TEMPLATES . '/menu.inc'; -require_once NEWS_TEMPLATES . '/edit/header.inc'; - -$img_dir = Horde_Themes::img(null, 'horde'); -foreach ($rows as $row) { - require NEWS_TEMPLATES . '/edit/row.php'; - if ($row['id'] == $id ) { - require NEWS_TEMPLATES . '/edit/info.php'; - } -} - -require NEWS_TEMPLATES . '/edit/footer.inc'; - -$form->renderActive(null, null, null, 'post'); - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/feed.php b/news/feed.php deleted file mode 100644 index 090cb310e..000000000 --- a/news/feed.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -function _getStories($feed_id) -{ - $stories = $GLOBALS['cache']->get('news_feed_' . $feed_id, $GLOBALS['conf']['cache']['default_lifetime']); - if (!$stories) { - $stories = $GLOBALS['registry']->call('news/stories', array($feed_id)); - $GLOBALS['cache']->set('news_feed_' . $feed_id, serialize($stories)); - return $stories; - } else { - return unserialize($stories); - } -} - -$feed_id = Horde_Util::getPost('feed_id'); -$stories = _getStories($feed_id); -$df = $GLOBALS['prefs']->getValue('date_format'); -foreach ($stories as $story) { - echo strftime($df, $story['story_published']) - . ' ' - . $story['story_title'] . '
'; -} diff --git a/news/files.php b/news/files.php deleted file mode 100644 index 749e00aea..000000000 --- a/news/files.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @package News - */ - -$no_compress = true; -require_once dirname(__FILE__) . '/lib/base.php'; - -$news_id = Horde_Util::getFormData('news_id', false); -$actionID = Horde_Util::getFormData('actionID'); -$file_id = Horde_Util::getFormData('file_id'); -$file_name = Horde_Util::getFormData('file_name'); -$news_lang = Horde_Util::getFormData('news_lang', News::getLang()); -$file_type = Horde_Util::getFormData('file_type'); -$file_size = Horde_Util::getFormData('file_size'); - -/* Run through action handlers. */ -switch ($actionID) { -case 'download_file': - $data = News::getFile($file_id); - if ($data instanceof PEAR_Error) { - if ($registry->isAdmin(array('permission' => 'news:admin'))) { - throw new Horde_Exception_Prior($data); - } else { - header('HTTP/1.0 404 Not Found'); - echo '

HTTP/1.0 404 Not Found

'; - } - exit; - } - - $browser->downloadHeaders($file_name, $file_type, false, $file_size); - echo $data; - break; - -case 'view_file': - - $data = News::getFile($file_id); - if ($data instanceof PEAR_Error) { - if ($registry->isAdmin(array('permission' => 'news:admin'))) { - throw new Horde_Exception_Prior($data); - } else { - header('HTTP/1.0 404 Not Found'); - echo '

HTTP/1.0 404 Not Found

'; - } - exit; - } - - $mime_part = new Horde_Mime_Part(); - $mime_part->setName($file_id); - $mime_part->setType($file_type); - $mime_part->setContents($data); - - $viewer = $injector->getInstance('Horde_Mime_Viewer')->getViewer($mime_part); - if ($viewer) { - $render = $viewer->render('full'); - if (!empty($render)) { - reset($render); - $key = key($render); - $browser->downloadHeaders($file_name, $render[$key]['type'], true, strlen($render[$key]['data'])); - echo $render[$key]['data']; - exit; - } - } - - // We cannnot see this file, so download it - $browser->downloadHeaders($file_name, $file_type, false, $file_size); - echo $data; - -break; - -case 'download_zip_all': - $file_id = sprintf(_("FilesOfNews-%s"), $news_id); - $zipfiles = array(); - foreach ($news->getFiles($news_id) as $file) { - $data = News::getFile($file_id); - if ($data instanceof PEAR_Error) { - continue; - } - $zipfiles[] = array('data' => $file_path, - 'name' => $file); - } - - if (empty($zipfiles)) { - exit; - } - - $zip = Horde_Compress::factory('zip'); - $body = $zip->compress($zipfiles); - $browser->downloadHeaders($news_id . '.zip', 'application/zip', false, strlen($body)); - echo $body; - -break; - -case 'download_zip': - $data = News::getFile($file_id); - if ($data instanceof PEAR_Error) { - if ($registry->isAdmin(array('permission' => 'news:admin'))) { - throw new Horde_Exception_Prior($data); - } else { - header('HTTP/1.0 404 Not Found'); - echo '

HTTP/1.0 404 Not Found

'; - } - exit; - } - - $zipfiles = array('data' => $data, 'name' => $file_id); - - $zip = Horde_Compress::factory('zip'); - $body = $zip->compress($zipfiles); - $browser->downloadHeaders($file_id . '.zip', 'application/zip', false, strlen($body)); - echo $body; - -break; -} - diff --git a/news/index.php b/news/index.php deleted file mode 100644 index 8fce8e83b..000000000 --- a/news/index.php +++ /dev/null @@ -1,14 +0,0 @@ - - * @package News - */ - -require NEWS_BASE . '/content.php'; diff --git a/news/js/feed.js b/news/js/feed.js deleted file mode 100644 index 1590ae4bf..000000000 --- a/news/js/feed.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Update news source feed - * - * $Id:$ - */ -function getFeed() { - - RedBox.loading(); - - new Ajax.Updater('feed_content', - document.feed_select.action, - { - onComplete: function() { - RedBox.close(); - }, - parameters: { - feed_id: $F('feed_id') - }, - onFailure: function() { - RedBox.close(); - alert('Error'); - }, - asynchronous: true - }); -} diff --git a/news/lib/Api.php b/news/lib/Api.php deleted file mode 100644 index 20cc271a9..000000000 --- a/news/lib/Api.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @package News - */ -class News_Api extends Horde_Registry_Api -{ - /** - * Callback for comment API - * - * @param int $id Internal data identifier - * @param string $type Type of data to retreive (title, owner...) - * @param array $params Additional parameters - */ - public function commentCallback($id, $type = 'title', $params = null) - { - static $info; - - if (!empty($info[$id][$type])) { - return $info[$id][$type]; - } - - require_once dirname(__FILE__) . '/base.php'; - - $news = $GLOBALS['news']->get($id); - if ($news instanceof PEAR_Error) { - return $news; - } - - switch ($type) { - - case 'owner': - return $news['user']; - - case 'link': - return News::getUrlFor('news', $id, true, -1); - - case 'messages': - $GLOBALS['news']->updateComments($id, $params); - - if ($GLOBALS['registry']->hasMethod('logActivity', 'folks')) { - $link = '' . $news['title'] . ''; - $message = sprintf(_("Has commented news \"%s\""), $link); - $GLOBALS['registry']->callByPackage('folks', 'logActivity', array($message, 'news')); - } - - return true; - - default: - $info[$id][$type] = $news['title']; - return $news['title']; - } - } - - /** - * Returns if applications allows comments - */ - public function hasComments() - { - return $GLOBALS['conf']['comments']['allow']; - } - - /** - * List news - * - * @param array $criteria Array of news attributes match - * @param intiger $from Start fetching from news - * @param intiger $count The number of news to fetch - * @param intiger $perms News permission access type - * - * @return array | PEAR_Error True on success, PEAR_Error on failure. - */ - public function listNews($criteria = array(), $from = 0, $count = 0, $perms = Horde_Perms::READ) - { - require_once dirname(__FILE__) . '/base.php'; - - return $GLOBALS['news']->listNews($criteria, $from, $count, $perms); - } - - /** - * Count news - * - * @param array $criteria Array of news attributes match - * @param integer $perms Permisson level - * - * @return integer | PEAR_Error True on success, PEAR_Error on failure. - */ - public function countNews($criteria = array(), $perms = Horde_Perms::READ) - { - require_once dirname(__FILE__) . '/base.php'; - - return $GLOBALS['news']->countNews($criteria, $perms); - } - -} diff --git a/news/lib/Application.php b/news/lib/Application.php deleted file mode 100644 index 82aa02ff7..000000000 --- a/news/lib/Application.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @package News - */ -class News_Application extends Horde_Registry_Application -{ - public $version = 'H4 (0.1-git)'; - - /** - * Returns a list of available permissions. - * - * @return array An array describing all available permissions. - */ - public function perms() - { - $perms = array( - 'admin' => array( - 'title' => _("Admin") - ), - 'categories' => array( - 'title' => _("Categories") - ), - 'editors' => array( - 'title' => _("Editors") - ) - ); - - require_once dirname(__FILE__) . '/base.php'; - $tree = $GLOBALS['news_cat']->getEnum(); - - foreach ($tree as $cat_id => $cat_name) { - $perms['categories:' . $cat_id] = array( - 'title' => $cat_name - ); - } - - return $perms; - } - - /** - * Add additional items to the menu. - * - * @param Horde_Menu $menu The menu object. - */ - public function menu($menu) - { - return News::getMenu(); - } - -} diff --git a/news/lib/Block/categories.php b/news/lib/Block/categories.php deleted file mode 100755 index 8420ff715..000000000 --- a/news/lib/Block/categories.php +++ /dev/null @@ -1,34 +0,0 @@ -getHtml(); - } -} \ No newline at end of file diff --git a/news/lib/Block/category.php b/news/lib/Block/category.php deleted file mode 100755 index 308261511..000000000 --- a/news/lib/Block/category.php +++ /dev/null @@ -1,65 +0,0 @@ -_params['category']); - $name = $GLOBALS['news_cat']->getName($this->_params['category']); - $html = Horde::link($url, sprintf(_("Last news in %s"), $name), 'header'); - $html .= sprintf(_("Last news in %s"), $name) . ''; - - return $html; - } - - function _params() - { - require_once dirname(__FILE__) . '/../base.php'; - - return array('limit' => array('type' => 'int', - 'name' => _("How many news to display?"), - 'default' => 10), - 'category' => array('type' => 'enum', - 'name' => _("Category"), - 'values' => $GLOBALS['news_cat']->getEnum())); - } - - function _content() - { - require_once dirname(__FILE__) . '/../base.php'; - - $query = 'SELECT n.id, n.publish, n.comments, n.picture, n.category1, nl.title, nl.abbreviation ' . - 'FROM ' . $GLOBALS['news']->prefix . ' AS n, ' . $GLOBALS['news']->prefix . '_body AS nl WHERE ' . - 'n.status = ? AND n.publish <= NOW() ' . - 'AND (n.category1 = ? OR n.category2 = ?) ' . - 'AND nl.lang = ? AND n.id = nl.id ' . - 'ORDER BY n.publish DESC'; - - $params = array(News::CONFIRMED, $this->_params['category'], $this->_params['category'], $GLOBALS['registry']->preferredLang()); - $res = $GLOBALS['news']->db->limitQuery($query, 0, $this->_params['limit'], $params); - if ($res instanceof PEAR_Error) { - return $res->getDebugInfo(); - } - $rows = array(); - while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) { - $rows[$row['id']] = $row; - } - $view = new News_View(); - $view->news = $rows; - $view->moreurl = Horde_Util::addParameter(Horde::url('browse.php'), 'category', $this->_params['category']); - - return $view->render('/block/news.php'); - } -} diff --git a/news/lib/Block/jonah.php b/news/lib/Block/jonah.php deleted file mode 100755 index 6431993cd..000000000 --- a/news/lib/Block/jonah.php +++ /dev/null @@ -1,58 +0,0 @@ -hasInterface('news')) { - $block_name = _("Press overview"); -} - -/** - * $Id: jonah.php 890 2008-09-23 09:58:23Z duck $ - * - * @package Horde_Block - */ -class Horde_Block_News_jonah extends Horde_Block { - - var $_app = 'news'; - - /** - * The title to go in this block. - * - * @return string The title text. - */ - function _title() - { - $url = $GLOBALS['registry']->get('webroot', 'jonah') . '/'; - return Horde::link($url, _("Press overview")) . _("Press overview") . ''; - } - - /** - * The content to go in this block. - * - * @return string The content - */ - function _content() - { - $html = '
'; - $html .= _("Select a feed."); - $html .= '
'; - - require_once dirname(__FILE__) . '/../base.php'; - - $sql = 'SELECT channel_id, channel_name ' - . ' FROM jonah_channels WHERE channel_type = 1 ORDER BY channel_name'; - $chanels = $GLOBALS['news']->db->getAll($sql); - - $html .= '
' - . '
'; - - Horde::addScriptFile('effects.js', 'horde'); - Horde::addScriptFile('redbox.js', 'horde'); - Horde::addScriptFile('feed.js', 'news'); - - return $html; - } -} diff --git a/news/lib/Block/last.php b/news/lib/Block/last.php deleted file mode 100755 index 36b0c95a8..000000000 --- a/news/lib/Block/last.php +++ /dev/null @@ -1,62 +0,0 @@ -'; - } - - function _params() - { - require_once dirname(__FILE__) . '/../base.php'; - - return array('limit' => array('type' => 'int', - 'name' => _("How many news to display?"), - 'default' => 10), - 'category' => array('type' => 'enum', - 'name' => _("Skip category"), - 'values' => $GLOBALS['news_cat']->getEnum())); - } - - function _content() - { - require_once dirname(__FILE__) . '/../base.php'; - - $params = array(News::CONFIRMED, $GLOBALS['registry']->preferredLang()); - $query = 'SELECT n.id, n.publish, n.comments, n.picture, n.category1, nl.title, nl.abbreviation ' . - 'FROM ' . $GLOBALS['news']->prefix . ' AS n, ' . $GLOBALS['news']->prefix . '_body AS nl WHERE ' . - 'n.status = ? AND n.publish <= NOW() ' . - 'AND nl.lang = ? AND n.id = nl.id '; - - if (!empty($this->_params['category'])) { - $query .= ' AND n.category1 <> ? '; - $params[] = (int)$this->_params['category']; - } - - $query .= 'ORDER BY n.publish DESC'; - $res = $GLOBALS['news']->db->queryLimit($query, 0, $this->_params['limit'], $params); - if ($res instanceof PEAR_Error) { - return $res->getDebugInfo(); - } - $rows = array(); - while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) { - $rows[$row['id']] = $row; - } - $view = new News_View(); - $view->news = $rows; - $view->moreurl = Horde::url('browse.php'); - - return $view->render('/block/news.php'); - } -} diff --git a/news/lib/Block/last_blogs.php b/news/lib/Block/last_blogs.php deleted file mode 100755 index 360e53cda..000000000 --- a/news/lib/Block/last_blogs.php +++ /dev/null @@ -1,48 +0,0 @@ - array('type' => 'int', - 'name' => _("How many news to display?"), - 'default' => 10)); - } - - function _content() - { - require_once dirname(__FILE__) . '/../base.php'; - - $query = 'SELECT n.id, n.publish, n.comments, n.picture, n.category1, nl.title, nl.abbreviation ' . - 'FROM ' . $GLOBALS['news']->prefix . ' AS n, ' . $GLOBALS['news']->prefix . '_body AS nl WHERE ' . - 'n.status = ? AND n.publish <= NOW() AND n.trackbacks > ? ' . - 'AND nl.lang = ? AND n.id = nl.id ' . - 'ORDER BY n.publish DESC'; - - $params = array(News::CONFIRMED, 0, $GLOBALS['registry']->preferredLang()); - $res = $GLOBALS['news']->db->limitQuery($query, 0, $this->_params['limit'], $params); - if ($res instanceof PEAR_Error) { - return $res->getDebugInfo(); - } - while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) { - $rows[$row['id']] = $row; - } - $view = new News_View(); - $view->news = $rows; - - return $view->render('/block/news.php'); - } -} diff --git a/news/lib/Block/last_comments.php b/news/lib/Block/last_comments.php deleted file mode 100755 index df6879a53..000000000 --- a/news/lib/Block/last_comments.php +++ /dev/null @@ -1,56 +0,0 @@ - array('name' => _("Number of comments to display"), - 'type' => 'int', - 'default' => 10)); - } - - /** - * The title to go in this block. - * - * @return string The title text. - */ - function _title() - { - return _("Last comments"); - } - - /** - * The content to go in this block. - * - * @return string The content - */ - function _content() - { - require_once dirname(__FILE__) . '/../News.php'; - - $comments = News::getLastComments($this->_params['limit']); - if ($comments instanceof PEAR_Error) { - return $comments; - } - - $html = ''; - foreach ($comments as $message) { - $html .= '- ' - . Horde::link($message['read_url']) . $message['message_subject'] . ' ' - . ' (' . $message['message_author'] . ')
'; - } - return $html; - } -} \ No newline at end of file diff --git a/news/lib/Block/most_commented.php b/news/lib/Block/most_commented.php deleted file mode 100755 index e683c95ec..000000000 --- a/news/lib/Block/most_commented.php +++ /dev/null @@ -1,55 +0,0 @@ - array('type' => 'int', - 'name' => _("How many news to display?"), - 'default' => 10), - 'days' => array('type' => 'int', - 'name' => _("How many days back to check?"), - 'default' => 30)); - } - - function _content() - { - require_once dirname(__FILE__) . '/../base.php'; - - $query = 'SELECT n.id, n.publish, n.comments, n.picture, n.category1, nl.title, nl.abbreviation ' . - 'FROM ' . $GLOBALS['news']->prefix . ' AS n, ' . $GLOBALS['news']->prefix . '_body AS nl WHERE ' . - 'n.status = ? AND n.publish <= NOW() AND n.publish > ?' . - 'AND nl.lang = ? AND n.id = nl.id ' . - 'ORDER BY n.comments DESC '; - - $younger = $_SERVER['REQUEST_TIME'] - $this->_params['days'] * 86400; - $params = array(News::CONFIRMED, date('Y-m-d', $younger), $GLOBALS['registry']->preferredLang()); - $res = $GLOBALS['news']->db->limitQuery($query, 0, $this->_params['limit'], $params); - if ($res instanceof PEAR_Error) { - return $res->getDebugInfo(); - } - $rows = array(); - while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) { - $rows[$row['id']] = $row; - } - $view = new News_View(); - $view->news = $rows; - - return $view->render('/block/titles.php'); - } -} diff --git a/news/lib/Block/most_read.php b/news/lib/Block/most_read.php deleted file mode 100755 index a64508599..000000000 --- a/news/lib/Block/most_read.php +++ /dev/null @@ -1,55 +0,0 @@ - array('type' => 'int', - 'name' => _("How many news to display?"), - 'default' => 10), - 'days' => array('type' => 'int', - 'name' => _("How many days back to check?"), - 'default' => 30)); - } - - function _content() - { - require_once dirname(__FILE__) . '/../base.php'; - - $query = 'SELECT n.id, n.publish, n.comments, n.picture, nl.title, nl.abbreviation ' . - 'FROM ' . $GLOBALS['news']->prefix . ' AS n, ' . $GLOBALS['news']->prefix . '_body AS nl WHERE ' . - 'n.status = ? AND n.publish <= NOW() AND n.publish > ?' . - 'AND nl.lang = ? AND n.id = nl.id ' . - 'ORDER BY n.view_count DESC'; - - $younger = $_SERVER['REQUEST_TIME'] - $this->_params['days'] * 86400; - $params = array(News::CONFIRMED, date('Y-m-d', $younger), $GLOBALS['registry']->preferredLang()); - $res = $GLOBALS['news']->db->queryLimit($query, 0, $this->_params['limit'], $params); - if ($res instanceof PEAR_Error) { - return $res->getDebugInfo(); - } - $rows = array(); - while ($res->fetchInto($row, DB_FETCHMODE_ASSOC)) { - $rows[$row['id']] = $row; - } - $view = new News_View(); - $view->news = $rows; - - return $view->render('/block/titles.php'); - } -} diff --git a/news/lib/Block/my_comments.php b/news/lib/Block/my_comments.php deleted file mode 100644 index 61ae08c2c..000000000 --- a/news/lib/Block/my_comments.php +++ /dev/null @@ -1,76 +0,0 @@ - array('name' => _("Number of comments to display"), - 'type' => 'int', - 'default' => 10)); - } - - /** - * The title to go in this block. - * - * @return string The title text. - */ - function _title() - { - return ("Last comments on my news"); - } - - /** - * The content to go in this block. - * - * @return string The content - */ - function _content() - { - if (!$GLOBALS['registry']->isAuthenticated()) { - return ''; - } - - $GLOBALS['cache'] = $GLOBALS['injector']->getInstance('Horde_Cache'); - - $cache_key = 'news_myscommetns_' . $this->_params['limit']; - $threads = $GLOBALS['cache']->get($cache_key, $GLOBALS['conf']['cache']['default_lifetime']); - if ($threads) { - return $threads; - } - - Horde::addScriptFile('tables.js', 'horde'); - $html = '' - . '' - . ''; - - try { - $threads = $GLOBALS['registry']->call('forums/getThreadsByForumOwner', - array($GLOBALS['registry']->getAuth(), 'message_timestamp', 1, false, - 'news', 0, $this->_params['limit'])); - } catch (Horde_Exception $e) { - return $e->getMessage(); - } - - foreach ($threads as $message) { - $html .= ''; - } - $html .= '
' . _("Title") . '' . _("User") . '
' - . '' - . $message['message_subject'] . ' ' - . '' - . $message['message_author'] . '
'; - - $GLOBALS['cache']->set($cache_key, $html); - return $html; - } -} diff --git a/news/lib/Block/sources.php b/news/lib/Block/sources.php deleted file mode 100755 index bb0197c22..000000000 --- a/news/lib/Block/sources.php +++ /dev/null @@ -1,44 +0,0 @@ -getSources(); - - $html = ''; - $url = Horde::url('browse.php'); - foreach ($sources as $source_id => $source_name) { - $html .= '- ' - . Horde::link(Horde_Util::addparameter($url, 'source_id', $source_id), '', '', '_blank') - . $source_name . '
'; - } - - return $html; - } -} diff --git a/news/lib/Block/tags_cloud.php b/news/lib/Block/tags_cloud.php deleted file mode 100644 index 9197897bb..000000000 --- a/news/lib/Block/tags_cloud.php +++ /dev/null @@ -1,38 +0,0 @@ -getCloud(true); - } -} \ No newline at end of file diff --git a/news/lib/Categories.php b/news/lib/Categories.php deleted file mode 100644 index 5defc52fe..000000000 --- a/news/lib/Categories.php +++ /dev/null @@ -1,615 +0,0 @@ - - * @package News - */ -class News_Categories { - - /** - * Hash containing connection parameters. - * - * @var array - */ - private $_params = array(); - - /** - * Handle for the current database connection. - * - * @var DB - */ - private $_db; - - /** - * Handle for the current database connection, used for writing. Defaults - * to the same handle as $db if a separate write database is not required. - * - * @var DB - */ - private $_write_db; - - /** - * An array containing all the tree nodes. - * - * @var array - */ - private $_nodes = array(); - - /** - * The top-level nodes in the tree. - * - * @var array - */ - private $_root_nodes = array(); - - /** - * An enumeratic array - * - * @var array - */ - private $_enum = array(); - - /** - * Has for view url link - * - * @var array - */ - private $_view_url; - - /** - * Handle for the tables prefix. - * - * @var prefix - */ - private $prefix = 'news'; - - /** - * Contruct the News object - */ - public function __construct($categoreis = null) - { - $this->_nodes = $this->getCategories(false); - if ($this->_nodes instanceof PEAR_Error) { - return $this->_nodes; - } - - foreach ($this->_nodes as $id => $category) { - if (empty($category['category_parentid'])) { - if (!in_array($id, $this->_root_nodes)) { - $this->_root_nodes[] = $id; - } - } else { - if (empty($this->_nodes[$category['category_parentid']]['children'])) { - $this->_nodes[$category['category_parentid']]['children'] = array(); - } - if (!in_array($id, $this->_nodes[$category['category_parentid']]['children'])) { - $this->_nodes[$category['category_parentid']]['children'][] = $id; - } - } - } - $this->_buildIndents($this->_root_nodes); - } - - /** - * Returns the string for category selection - * - * @return string - */ - public function getSelect() - { - $output = ''; - foreach ($this->_root_nodes as $node_id) { - $output .= $this->_buildSelect($node_id); - } - - return $output; - } - - /** - * - */ - private function _buildSelect($node_id) - { - $output = ''; - - if (isset($this->_nodes[$node_id]['children'])) { - $num_subnodes = count($this->_nodes[$node_id]['children']); - for ($c = 0; $c < $num_subnodes; $c++) { - $child_node_id = $this->_nodes[$node_id]['children'][$c]; - $output .= $this->_buildSelect($child_node_id); - } - } - - return $output; - } - - /** - * Returns the enumeratic array for select form pameter. - * - * @return array The category array (cat => name) - */ - public function getEnum() - { - if (empty($this->_enum)) { - foreach ($this->_root_nodes as $node_id) { - $this->_buildEnum($node_id); - } - } - - return $this->_enum; - } - - private function _buildEnum($node_id) - { - $this->_enum[$node_id] = str_repeat(' - ', $this->_nodes[$node_id]['indent']) - . $this->_nodes[$node_id]['category_name']; - - if (isset($this->_nodes[$node_id]['children'])) { - $num_subnodes = count($this->_nodes[$node_id]['children']); - for ($c = 0; $c < $num_subnodes; $c++) { - $child_node_id = $this->_nodes[$node_id]['children'][$c]; - $this->_buildEnum($child_node_id); - } - } - } - - /** - * Returns html for category selection - * - * @return string - */ - public function getHtml() - { - $this->_view_url = News::getUrlFor('category', ''); - - $output = ''; - foreach ($this->_root_nodes as $node_id) { - $output .= $this->_buildHtml($node_id); - } - - return $output; - } - - private function _buildHtml($node_id) - { - $output = ''; - if ($this->_nodes[$node_id]['indent'] == 0) { - $output .= ''; - } - $url = $this->_view_url . $node_id; - $output .= Horde::link($url) . $this->_nodes[$node_id]['category_name'] . ', '; - if ($this->_nodes[$node_id]['indent'] == 0) { - $output .= '
'; - } - - if (isset($this->_nodes[$node_id]['children'])) { - $num_subnodes = count($this->_nodes[$node_id]['children']); - for ($c = 0; $c < $num_subnodes; $c++) { - $child_node_id = $this->_nodes[$node_id]['children'][$c]; - $output .= $this->_buildHtml($child_node_id); - } - } - - return $output; - } - - /** - * Set the indent level for each node in the tree. - */ - private function _buildIndents($nodes, $indent = 0) - { - foreach ($nodes as $id) { - $this->_nodes[$id]['indent'] = $indent; - if (!empty($this->_nodes[$id]['children'])) { - $this->_buildIndents($this->_nodes[$id]['children'], $indent + 1); - } - } - } - - /** - * Returns array of cateogriy children id - * - * @return array - */ - public function getChildren($id) - { - if (!empty($this->_nodes[$id]['children'])) { - return $this->_nodes[$id]['children']; - } else { - return array(); - } - } - - /** - * Returns the current language - * - * @return string The current language. - */ - public function getAllowed($perm = Horde_Perms::SHOW) - { - $cats = $this->getCategories(); - $perms = $GLOBALS['injector']->getInstance('Horde_Perms'); - - if ($GLOBALS['registry']->isAdmin(array('permission' => 'news:admin')) || - $perms->hasPermission('news', $GLOBALS['registry']->getAuth(), $perm)) { - return $cats; - } - - foreach ($cats as $key => $value) { - // user has access? - if (!$perms->hasPermission('news:categories', $GLOBALS['registry']->getAuth(), $perm) && // master - !$perms->hasPermission('news:categories:' . $key, $GLOBALS['registry']->getAuth(), $perm) && // child - !$perms->hasPermission('news:categories:' . $this->_nodes[$key]['category_parentid'], $GLOBALS['registry']->getAuth(), $perm) // father - ) { - unset($cats[$key]); - } - } - - return $cats; - } - - /** - * Returns the name for category - * - * @return string - */ - public function getName($id) - { - $cats = $this->getCategories(); - return $cats[$id]; - } - - /** - * Returns the full name of a category - * - * @return string - */ - public function getFullName($id) - { - static $names; - - if (isset($names[$id])) { - return $names[$id]; - } elseif (empty($id)) { - return $GLOBALS['registry']->get('name'); - } - - $cats = $this->getCategories(false); - $names[$id] = ''; - $parent = $cats[$id]['category_parentid']; - - while ($parent) { - $names[$id] .= $cats[$parent]['category_name'] . ': '; - $parent = $cats[$parent]['category_parentid']; - } - - $names[$id] .= $cats[$id]['category_name']; - - return $names[$id]; - } - - /** - * Save a category data into the backend from edit form. - * - * @param array $info The category data to save. - * - * @return mixed PEAR error. - */ - public function saveCategory($info) - { - $this->_connect(); - - /* Update/Insert category. */ - if (!empty($info['category_id'])) { - $result = $this->_updateCategory($info['category_id'], $info); - if ($result instanceof PEAR_Error) { - return $result; - } - } else { - $info['category_id'] = $this->_insertCategory($info); - if ($info['category_id'] instanceof PEAR_Error) { - return $info['category_id']; - } - } - - /* If image uploaded save to backend. */ - if (!empty($info['category_image']['name'])) { - $image = News::saveImage($info['category_image']['file'], $info['category_id'], 'categories', $info['image_resize']); - if ($image instanceof PEAR_Error) { - return $image; - } - - $sql = 'UPDATE ' . $this->prefix . '_categories SET category_image = ? WHERE category_id = ?'; - $this->_write_db->query($sql, array(1, $info['category_id'])); - } - - // Clean cache - $this->_expireCache(); - - return $info['category_id']; - } - - /** - * Insert category data. - * - * @param mixed $data The category data to insert. - * - * @return array Inserted ID or PEAR error. - */ - private function _insertCategory($data) - { - $new_id = $this->_write_db->nextId('news_categories'); - if ($new_id instanceof PEAR_Error) { - Horde::logMessage($new_id, 'ERR'); - return $new_id; - } - - $sql = 'INSERT INTO ' . $this->prefix . '_categories' . - ' (category_id, category_parentid) VALUES (?, ?)'; - $values = array($new_id, (int)$data['category_parentid']); - - $category = $this->_write_db->query($sql, $values); - if ($category instanceof PEAR_Error) { - Horde::logMessage($category, 'ERR'); - return $category; - } - - $sql = 'INSERT INTO ' . $this->prefix . '_categories_nls VALUES (?, ?, ?, ?)'; - foreach ($GLOBALS['conf']['attributes']['languages'] as $lang) { - - $values = array($new_id, - $lang, - $data['category_name_' . $lang], - $data['category_description_' . $lang]); - $result = $this->_write_db->query($sql, $values); - if ($result instanceof PEAR_Error) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } - - return $new_id; - } - - /** - * Update category data. - * - * @param integer $category_id The category id to update. - * @param array $data The category data to update. - * - * @return array NULL or PEAR error. - */ - private function _updateCategory($category_id, $data) - { - $sql = 'UPDATE ' . $this->prefix . '_categories' . - ' SET category_parentid = ? ' . - ' WHERE category_id = ?'; - $values = array((int)$data['category_parentid'], $category_id); - - $category = $this->_write_db->query($sql, $values); - if ($category instanceof PEAR_Error) { - Horde::logMessage($category, 'ERR'); - return $category; - } - - $sql = 'UPDATE ' . $this->prefix . '_categories_nls SET ' - . ' category_name = ?, category_description = ? WHERE ' - . ' category_id = ? AND category_nls = ?'; - foreach ($GLOBALS['conf']['attributes']['languages'] as $lang) { - $values = array($data['category_name_' . $lang], - $data['category_description_' . $lang], - $category_id, - $lang); - $result = $this->_write_db->query($sql, $values); - } - - return $result; - } - - /** - * Delete a category - * - * @return booelan - */ - public function deleteCategory($id) - { - // Clean cache - $this->_expireCache(); - - // Delete image - News::deleteImage($id, 'categories'); - - // Delete record - $this->_connect(); - $this->_write_db->query('DELETE FROM ' . $this->prefix . '_categories WHERE category_id = ?', array($id)); - return $this->_write_db->query('DELETE FROM ' . $this->prefix . '_categories_nls WHERE category_id = ?', array($id)); - } - - /** - * Return an array of data for edit form. - * - * @param $cid The category ID. - * - * @return mixed Array that hold data for edit form. - */ - function getCatArray($cid) - { - $this->_connect(); - - $sql = 'SELECT c.category_parentid, c.category_image, ' - . ' l.category_nls, l.category_name, l.category_description ' - . ' FROM news_categories c, news_categories_nls l ' - . ' WHERE c.category_id = ? AND c.category_id = l.category_id'; - - $category = array('category_id' => $cid); - $result = $this->_db->getAll($sql, array($cid), DB_FETCHMODE_ASSOC); - - foreach ($result as $row) { - $category['category_parentid'] = $row['category_parentid']; - $category['category_image'] = $row['category_image']; - $category['category_name_' . $row['category_nls']] = $row['category_name']; - $category['category_description_' . $row['category_nls']] = $row['category_description']; - } - - return $category; - } - - /** - * Return a Horde_Tree representation of the News_Categories tree. - * - * @return string The html showing the categories as a Horde_Tree. - */ - function renderTree($current = null, $click_url = null, $browse_only = false, $have_add_item = false) - { - $cats = $this->getCategories(false); - - $params = array('icon' => Horde_Themes::img('folder_open.png')); - - // Set up the tree - $tree = $GLOBALS['injector']->getInstance('Horde_Tree')->getTree('news_cats', 'Javascript', array( - 'alternate' => true, - 'border' => '0', - 'cellpadding' => '0', - 'cellspacing' => '0', - 'class' => 'item', - 'width' => '100%' - )); - - // prepare add link - if ($have_add_item) { - $add_img = Horde::img('mkdir.png', _("Add New Item")); - $add_item = Horde::url('items/edit.php'); - } - - foreach ($cats as $cid => $category) { - - if ($click_url !== null) { - $name = Horde::link(Horde_Util::addParameter($click_url, 'cid', $cid), _("Select Category")) . $category['category_name'] . ''; - } else { - $name = $category['category_name']; - } - - $links = array(); - if ($have_add_item) { - $links[] = Horde::link(Horde_Util::addParameter($add_item, 'cid', $cid), _("Add New Item")) . $add_img . ''; - } - - $parent_id = $category['category_parentid'] ? $category['category_parentid'] : null; - $tree->addNode($cid, $parent_id, $name, $this->_nodes[$cid]['indent'], true, $params, $links); - } - - - return $tree->renderTree(); - } - - /** - * Get category child list - */ - public function getChildList($id) - { - return isset($this->_nodes[$id]['children']) ? $this->_nodes[$id]['children'] : array(); - } - - /** - * Return a stored image for a category. - * - * @param integer $cid The id of the category requested. - * - * @return string The image name. - */ - function getImage($cid) - { - /* Check if there is an image for requested category. */ - if (!isset($this->_nodes[$cid]['category_image'])) { - return ''; - } - - /* return url */ - if ($GLOBALS['conf']['images']['direct']) { - return Horde::img('/categories/' . $cid . '.' . $GLOBALS['conf']['images']['image_type'], $cid, '', $GLOBALS['conf']['images']['direct']); - } else { - $img_params = array('f' => $cid . '.' . $GLOBALS['conf']['images']['image_type'], - 's' => 'vfs', - 'p' => self::VFS_PATH . '/images/categories/', - 'c' => 'news'); - return Horde_Util::addParameter(Horde::url('/services/images/view.php'), $img_params); - } - } - - /** - * Get available categories - * - * @return array An array containing caegories - */ - public function getCategories($flat = true) - { - $lang = News::getLang(); - $cache_key = 'NewsCategories_' . $lang . '_' . (int)$flat; - $categories = $GLOBALS['cache']->get($cache_key, $GLOBALS['conf']['cache']['default_lifetime']); - if ($categories) { - return unserialize($categories); - } - - $this->_connect(); - - $sql = 'SELECT c.category_id, l.category_name, c.category_parentid, l.category_description, c.category_image ' - . ' FROM ' . $this->prefix . '_categories c, ' . $this->prefix . '_categories_nls l ' - . ' WHERE c.category_id = l.category_id AND l.category_nls = ? ORDER BY category_name ASC'; - $result = $this->_db->getAssoc($sql, false, array($lang), DB_FETCHMODE_ASSOC); - - if ($result instanceof PEAR_Error) { - return $result; - } - - if (!$flat) { - $GLOBALS['cache']->set($cache_key, serialize($result)); - return $result; - } - - $categories = array(); - foreach ($result as $category_id => $row) { - if (!empty($row['category_description']) && $row['category_name'] != $row['category_description']) { - $row['category_name'] .= ' [ ' . $row['category_description'] . ' ]'; - } - $categories[$category_id] = $row['category_name']; - } - - $GLOBALS['cache']->set($cache_key, serialize($categories)); - return $categories; - } - - /** - * Expire categories cache - */ - private function _expireCache() - { - $langs = $GLOBALS['conf']['attributes']['languages']; - $langs[] = News::getLang(); - - foreach ($langs as $lang) { - $GLOBALS['cache']->expire('NewsCategories_' . $lang . '_0'); - $GLOBALS['cache']->expire('NewsCategories_' . $lang . '_1'); - } - } - - /** - * Attempts to open a persistent connection to the SQL server. - * - * @return boolean True on success. - */ - private function _connect() - { - $this->_db = $GLOBALS['news']->db; - $this->_write_db = $GLOBALS['news']->write_db; - } -} diff --git a/news/lib/Driver.php b/news/lib/Driver.php deleted file mode 100644 index bd27be06e..000000000 --- a/news/lib/Driver.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @package News - */ -class News_Driver { - - /** - * Hash containing connection parameters. - * - * @var array - */ - protected $_params = array(); - - /** - * Attempts to return a concrete News_Driver instance based on $driver. - * - * @param string $driver The type of the concrete News_Driver subclass - * to return. The class name is based on the - * storage driver ($driver). The code is - * dynamically included. - * - * @param array $params A hash containing any additional configuration - * or connection parameters a subclass might need. - * - * @return News_Driver The newly created concrete News_Driver. - * @throws Horde_Exception - */ - static function factory($driver = 'sql', $params = array()) - { - $class_name = 'News_Driver_' . $driver; - require_once NEWS_BASE . '/lib/Driver/' . $driver . '.php'; - - if (!class_exists($class_name)) { - throw new Horde_Exception('DRIVER MISSING'); - } - - return new $class_name($params); - } - - /** - * Get news - * - * @param int $news news id - * - * @return true on succes PEAR_Error on failure - */ - public function get($id) - { - // Admins bypass the cache (can read nonpublished and locked news) - if (!$GLOBALS['registry']->isAdmin(array('permission' => 'news:admin'))) { - $key = 'news_' . News::getLang() . '_' . $id; - $data = $GLOBALS['cache']->get($key, $GLOBALS['conf']['cache']['default_lifetime']); - if ($data) { - return unserialize($data); - } - } - - $data = $this->_get($id); - if ($data instanceof PEAR_Error) { - return $data; - } - - if (!$GLOBALS['registry']->isAdmin(array('permission' => 'news:admin'))) { - $GLOBALS['cache']->set($key, serialize($data)); - } - - return $data; - } -} diff --git a/news/lib/Driver/sql.php b/news/lib/Driver/sql.php deleted file mode 100644 index bf8f8ec71..000000000 --- a/news/lib/Driver/sql.php +++ /dev/null @@ -1,583 +0,0 @@ - - * @package News - */ -class News_Driver_sql extends News_Driver { - - /** - * Handle for the current database connection. - * - * @var DB - */ - public $db; - - /** - * Handle for the current database connection, used for writing. Defaults - * to the same handle as $db if a separate write database is not required. - * - * @var DB - */ - public $write_db; - - /** - * Handle for the tables prefix. - * - * @var prefix - */ - public $prefix = 'news'; - - /** - * Constructor - */ - public function __construct() - { - $this->_params = Horde::getDriverConfig('storage', 'sql'); - $this->_connect(); - } - - /** - * Updates schedul comments counter - * - * @param int $id schedul id - * - * @return true on succes PEAR_Error on failure - */ - public function updateComments($id, $count) - { - return $this->write_db->query('UPDATE ' . $this->prefix . ' SET comments = ? WHERE id = ?', array($count, $id)); - } - - /** - * Get news - * - * @param int $news news id - * - * @return true on succes PEAR_Error on failure - */ - protected function _get($id) - { - $query = 'SELECT n.publish, n.user, n.source, n.sourcelink, n.category1, n.parents, ' . - ' n.category2, n.attachments, n.picture, n.comments, n.gallery, n.sponsored, ' . - ' l.title, l.content, l.picture_comment, l.tags, n.selling, n.trackbacks, n.threads, ' . - ' n.form_id, n.form_ttl FROM ' . $this->prefix . ' AS n, ' . $this->prefix . '_body AS l ' . - ' WHERE n.id = ? AND n.id=l.id AND l.lang = ?'; - - /** TODO Allow for now to allow static linked news, but not shown in list - if (!$registry->isAdmin(array('permission' => 'news:admin'))) { - $query .= ' AND n.status = ' . News::CONFIRMED; - } - */ - - $data = $this->db->getRow($query, array($id, News::getLang()), DB_FETCHMODE_ASSOC); - if ($data instanceof PEAR_Error) { - return $data; - } - - if (empty($data)) { - return PEAR::raiseError(sprintf(_("There requested news %s don't exist."), $id)); - } - - /* Get talks backs */ - if ($data['trackbacks']) { - $sql = 'SELECT excerpt, created, title, url, blog_name FROM ' . $this->prefix . '_trackback WHERE id = ?'; - $data['trackback'] = $this->db->getAll($sql, array($id), DB_FETCHMODE_ASSOC); - if ($data['trackback'] instanceof PEAR_Error) { - return $data['trackback']; - } - } - - /* Get parents */ - if ($data['parents']) { - $sql = 'SELECT n.id, n.publish, n.comments, l.title ' . - ' FROM ' . $this->prefix . ' AS n, ' . $this->prefix . '_body AS l ' . - ' WHERE n.id IN (' . $data['parents'] . ') AND n.id = l.id AND l.lang = ?'; - $data['parents'] = $this->db->getAssoc($sql, false, array(News::getLang()), DB_FETCHMODE_ASSOC); - if ($data['parents'] instanceof PEAR_Error) { - return $data['parents']; - } - } - - /* Get threads */ - if ($data['threads']) { - $sql = 'SELECT message_id, forum_id, message_subject, message_seq ' . - ' FROM agora_messages WHERE message_id IN (' . $data['threads'] . ')'; - $data['threads'] = $this->db->getAssoc($sql, false, null, DB_FETCHMODE_ASSOC); - if ($data['threads'] instanceof PEAR_Error) { - return $data['threads']; - } - } - - return $data; - } - - /** - * Get news attached files - * - * @param int $news_id news id - * @param string $news_lang news language - * - * @return true on succes PEAR_Error on failure - */ - public function getFiles($news_id, $news_lang = null) - { - if (is_null($news_lang)) { - $news_lang = News::getLang(); - } - - $sql = 'SELECT file_id, news_id, news_lang, file_name, file_size, file_type FROM ' . $this->prefix . '_files' - . ' WHERE news_id = ? AND news_lang = ?'; - - return $this->db->getAll($sql, array($news_id, $news_lang), DB_FETCHMODE_ASSOC); - } - - /** - * Get version - * - * @param intiger $id news id - * @param array $info array with all news info - * - * @return result of the insert - */ - public function getVerison($id, $version) - { - $sql = 'SELECT id, created, user_uid, content FROM ' . $this->prefix . '_versions WHERE id = ? AND version = ?'; - $result = $this->db->getRow($sql, array($id, $version), DB_FETCHMODE_ASSOC); - $result['content'] = unserialize($result['content']); - return $result; - } - - /** - * Get versions - * - * @param intiger $id news id - * @param array $info array with all news info - * - * @return result of the insert - */ - public function getVerisons($id) - { - $sql = 'SELECT version, created, user_uid, content, action FROM ' . $this->prefix . '_versions WHERE id = ? ORDER BY version DESC'; - return $this->db->getAll($sql, array($id), DB_FETCHMODE_ASSOC); - } - - /** - * Logs a news view. - * - * @return boolean True, if the view was logged, false if the message was aleredy seen - */ - public function logView($id) - { - if ($GLOBALS['browser']->isRobot()) { - exit; - } - - /* We already read this story? */ - if (isset($_COOKIE['news_viewed_news']) && - strpos($_COOKIE['news_viewed_news'], ':' . $id . '|') !== false) { - return false; - } - - /* Rembember when we see a story */ - if (!isset($_COOKIE['news_viewed_news'])) { - $_COOKIE['news_viewed_news'] = ':'; - } - $_COOKIE['news_viewed_news'] .= $id . '|' . $_SERVER['REQUEST_TIME'] . ':'; - - setcookie('news_viewed_news', $_COOKIE['news_viewed_news'], $_SERVER['REQUEST_TIME'] + 22896000, $GLOBALS['conf']['cookie']['path'], - $GLOBALS['conf']['cookie']['domain'], $GLOBALS['conf']['use_ssl'] == 1 ? 1 : 0); - - /* Update the count */ - $sql = 'UPDATE ' . $this->prefix . ' SET view_count = view_count + 1 WHERE id = ?'; - $result = $this->write_db->query($sql, array($id)); - if ($result instanceof PEAR_Error) { - return $result; - } - - /* Log it */ - $sql = 'INSERT INTO ' . $this->prefix . '_user_reads (id,user,ip,useragent,readdate) VALUES (?, ?, ? , ?, NOW())'; - $result = $this->write_db->query($sql, array($id, $GLOBALS['registry']->getAuth(), $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'])); - if ($result instanceof PEAR_Error) { - return $result; - } - - return true; - } - - /** - * Attach a trackback - */ - public function saveTrackback($id, $title, $url, $excerpt, $blog_name, $trackback_url) - { - $sql = 'SELECT COUNT(*) FROM ' . $this->prefix . '_trackback WHERE id = ? AND url = ?'; - $result = $this->db->getOne($sql, array($id, $url)); - if ($result > 0) { - return PEAR::raiseError(sprintf(_("URL already trackbacked: %s"), $url)); - } - - $params = array('id' => $id, - 'title' => $title, - 'url' => $url, - 'excerpt' => $excerpt, - 'blog_name' => $blog_name, - 'created' => date('Y-m-d H:i:s')); - - $sql = 'INSERT INTO ' . $this->prefix . '_trackback (' . implode(',', array_keys($params)) . ') VALUES (?, ?, ?, ?, ?, ?)'; - $result = $this->write_db->query($sql, $params); - if ($result instanceof PEAR_Error) { - return $result; - } - - /* Update trackback count */ - $GLOBALS['cache']->expire('news_' . News::getLang() . '_' . $id); - return $this->write_db->query('UPDATE ' . $this->prefix . ' SET trackbacks = trackbacks + 1 WHERE id = ?', array($id)); - } - - /** - * Delete a source - * - * @param integer $id The source id to delete. - * - * @return boolean - */ - public function deleteSource($id) - { - $GLOBALS['cache']->expire('newsSources'); - $this->deleteImage($id, 'sources'); - $sql = 'DELETE FROM ' . $this->prefix . '_sources WHERE sources_id = ?'; - return $this->write_db->query($sql, array($id)); - } - - /** - * Fetches sources list - * - * @return array An array containing all sources names - */ - public function getSources($flat = false) - { - $sources = $GLOBALS['cache']->get('newsSources'); - if (empty($sources)) { - $sql = 'SELECT source_id, source_name, source_url FROM ' . $this->prefix . '_sources ORDER BY source_name ASC'; - $sources = $this->db->getAssoc($sql, true, array(), DB_FETCHMODE_ASSOC); - $GLOBALS['cache']->set('newsSources', serialize($sources)); - } else { - $sources = unserialize($sources); - } - - if (!$flat) { - foreach ($sources as $source_id => $source) { - $sources[$source_id] = $source['source_name']; - } - } - - return $sources; - } - - /** - * Save a source data into the backend from edit form. - * - * @param array $info The source data to save. - * - * @return mixed PEAR error. - */ - public function saveSource($info) - { - /* Update/Insert source. */ - if (!empty($info['source_id'])) { - $result = $this->_updateSource($info['source_id'], $info); - if ($result instanceof PEAR_Error) { - return $result; - } - } else { - $info['source_id'] = $this->_insertSource($info); - if ($info['source_id'] instanceof PEAR_Error) { - return $info['source_id']; - } - } - - /* If image uploaded save to backend. */ - if (!empty($info['source_image']['name'])) { - $image = $this->_saveImage($info['source_id'], $info['source_image']['file'], 'sources', $info['source_image_resize']); - if ($image instanceof PEAR_Error) { - return $image; - } - - $sql = 'UPDATE ' . $this->prefix . '_sources SET source_image = ? WHERE source_id = ?'; - $this->write_db->query($sql, array(1, $info['source_id'])); - } - - $GLOBALS['cache']->expire('newsSources'); - return $info['source_id']; - } - - /** - * Insert source data. - * - * @param mixed $data The source data to insert. - * - * @return array Inserted ID or PEAR error. - */ - private function _insertSource($data) - { - $new_id = $this->write_db->nextId('news_sources'); - - $sql = 'INSERT INTO ' . $this->prefix . '_sources' . - ' (source_id, source_name, source_url)' . - ' VALUES (?, ?, ?)'; - $values = array($new_id, - $data['source_name'], - $data['source_url']); - - $source = $this->write_db->query($sql, $values); - if ($source instanceof PEAR_Error) { - Horde::logMessage($source, 'ERR'); - return $source; - } - - return $new_id; - } - - /** - * Update source data. - * - * @param integer $source_id The source id to update. - * @param array $data The source data to update. - * - * @return array NULL or PEAR error. - */ - private function _updateSource($source_id, $data) - { - $sql = 'UPDATE ' . $this->prefix . '_sources' . - ' SET source_name = ?, source_url = ?' . - ' WHERE source_id = ?'; - $values = array($data['source_name'], - $data['source_url'], - $source_id); - - $source = $this->write_db->query($sql, $values); - if ($source instanceof PEAR_Error) { - Horde::logMessage($source, 'ERR'); - return $source; - } - } - - /** - * Attempts to open a persistent connection to the SQL server. - * - * @return boolean True on success. - * @throws Horde_Exception - */ - private function _connect() - { - $this->_db = $GLOBALS['injector']->getInstance('Horde_Db_Pear')->getDb('read', 'news', 'storage'); - $this->_write_db = $GLOBALS['injector']->getInstance('Horde_Db_Pear')->getDb('rw', 'news', 'storage'); - - if (isset($this->_params['prefix'])) { - $this->prefix = $this->_params['prefix']; - } - - return true; - } - - /** - * Build whare search - */ - public function buildQuery($perms = Horde_Perms::READ, $criteria = array()) - { - static $parts; - - $id = serialize($criteria); - if (isset($parts[$id])) { - return $parts[$id]; - } - - $sql = 'FROM ' . $GLOBALS['news']->prefix . ' AS n, ' . $GLOBALS['news']->prefix . '_body AS l ' - . ' WHERE n.id = l.id AND l.lang = ?'; - $params = array('_lang' => $GLOBALS['registry']->preferredLang()); - - if ($perms == Horde_Perms::READ) { - $sql .= ' AND n.publish <= ? '; - $params['_perms'] = date('Y-m-d H:i:s'); - $sql .= ' AND n.status = ? '; - $params['_status'] = News::CONFIRMED; - } - - if (empty($criteria)) { - $parts[$id] = array($sql, $params); - return $parts[$id]; - } - - /* check status */ - if (isset($criteria['status'])) { - $sql .= ' AND n.status = ?'; - $params['status'] = $criteria['status']; - } - - /* check status */ - if (isset($criteria['source'])) { - $sql .= ' AND n.source = ?'; - $params['source'] = $criteria['source']; - } - - /* get category */ - if (isset($criteria['category'])) { - $sql .= ' AND (n.category1 = ? OR n.category2 = ?)'; - $params['category'] = $criteria['category']; - $params['_category'] = $criteria['category']; - } - - /* seaching for a pericolar word */ - if (isset($criteria['word'])) { - $sql .= ' AND (l.title LIKE ? OR l.content LIKE ? OR l.tags LIKE ?)'; - $params['word'] = '%' . $criteria['word'] . '%'; - $params['_word'] = '%' . $criteria['word'] . '%'; - $params['tags'] = '%' . $criteria['word'] . '%'; - } - - /* submitter */ - if (isset($criteria['user'])) { - $sql .= ' AND n.user = ? '; - $params['user'] = $criteria['user']; - } - - /* editor */ - if (isset($criteria['editor'])) { - $sql .= ' AND n.editor = ? '; - $params['editor'] = $criteria['editor']; - } - - /* publish time */ - if (isset($criteria['published_to'])) { - $sql .= ' AND n.publish <= ? '; - $params['published_to'] = $criteria['published_to']; - } - - if (isset($criteria['published_from'])) { - $sql .= ' AND n.publish >= ? '; - $params['published_from'] = $criteria['published_from']; - } - - $parts[$id] = array($sql, $params); - - return $parts[$id]; - } - - /** - * Count news - * - * @param array $criteria Filter parameter - - * @param int $perms Permissions filter - * - * @return Nimber of news - */ - public function countNews($criteria = array(), $perms = Horde_Perms::READ) - { - $binds = $this->buildQuery($perms, $criteria); - $binds[0] = 'SELECT COUNT(*) ' . $binds[0]; - - return $this->db->getOne($binds[0], $binds[1]); - } - - /** - * List news - * - * @param array $criteria Filter parameter - * @param int $from Offset - * @param int $count Limit rows - * @param int $perms Permissions filter - * - * @return array of news data - */ - public function listNews($criteria = array(), $from = 0, $count = 0, $perms = Horde_Perms::READ) - { - $binds = $this->buildQuery($perms, $criteria); - - if (!isset($criteria['sort_by'])) { - $criteria['sort_by'] = 'n.publish'; - } - if (!isset($criteria['sort_dir'])) { - $criteria['sort_dir'] = 'DESC'; - } - - $binds[0] = 'SELECT n.id, n.publish, n.user, n.category1, n.category2, n.comments, ' - . ' n.picture, n.chars, l.title, l.abbreviation ' . $binds[0] - . ' ORDER BY ' . $criteria['sort_by'] - . ' ' . $criteria['sort_dir']; - - if ($count) { - $binds[0] = $this->db->modifyLimitQuery($binds[0], $from, $count); - } - - return $this->db->getAll($binds[0], $binds[1], DB_FETCHMODE_ASSOC); - } - - /** - * Construct tag cloud - * - * @param boolean $minimize Minimize tag cloud - * (remove 1 length strings, and single occurrence) - * - * @return mixed The HTML for the tag cloud | PEAR_Error - */ - public function getCloud($minimize = false) - { - $cache_key = 'news_cloud_' . $minimize; - $cloud = $GLOBALS['cache']->get($cache_key, $GLOBALS['conf']['cache']['default_lifetime']); - if ($cloud) { - return $cloud; - } - - $sql = 'SELECT l.tags, n.publish FROM ' . $this->prefix . '_body AS l, ' - . $this->prefix . ' AS n WHERE l.lang = ? AND n.id = l.id AND n.status = ? ORDER BY n.publish DESC'; - - $result = $this->db->limitQuery($sql, 0, ($minimize ? '100' : '500'), array($GLOBALS['registry']->preferredLang(), News::CONFIRMED)); - if ($result instanceof PEAR_Error) { - return $result; - } - - $tags_elemets = array(); - while ($news = $result->fetchRow(DB_FETCHMODE_ASSOC)) { - foreach (explode(' ', $news['tags']) as $tag) { - if ($minimize && strlen($tag) < 2) { - continue; - } - $tags_elemets[$tag][] = strtotime($news['publish']); - } - } - - if ($minimize) { - foreach ($tags_elemets as $tag => $content) { - if (count($content) == 1) { - unset($tags_elemets[$tag]); - } - } - } - - if (empty($tags_elemets)) { - return ''; - } - - $i = 0; - $tags = new News_TagCloud(); - $tag_link = Horde::url('search.php'); - foreach ($tags_elemets as $tag => $time) { - sort($time); - $tags->addElement($tag, Horde_Util::addParameter($tag_link, array('word' => $tag)), - count($tags_elemets[$tag]), $time[0]); - } - - $cloud = $tags->buildHTML(); - $GLOBALS['cache']->set($cache_key, $cloud); - - return $cloud; - } - -} diff --git a/news/lib/Forms/Search.php b/news/lib/Forms/Search.php deleted file mode 100644 index 97cb035a6..000000000 --- a/news/lib/Forms/Search.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @package News - */ -class News_Search extends Horde_Form { - - /** - * Creator - */ - public function __construct($vars) - { - parent::__construct($vars, _("Search"), 'news_search'); - - $this->_submit = _("Search"); - - $this->addVariable(_("Search world"), 'word', 'text', false, false, false); - - $s = array(News::UNCONFIRMED => _("Unconfirmed"), - News::CONFIRMED => _("Confirmed"), - News::LOCKED => _("Locked")); - $this->addVariable(_("Status"), 'status', 'enum', false, false, false, array($s, _("-- select --"))); - - $allowed_cats = $GLOBALS['news_cat']->getAllowed(Horde_Perms::DELETE); - $this->addVariable(_("Category"), 'category', 'enum', false, false, false, array($allowed_cats, _("-- select --"))); - - $sources = $GLOBALS['news']->getSources(); - if (!empty($sources)) { - $this->addVariable(_("Source"), 'source', 'enum', false, false, false, array($sources, _("-- select --"))); - } - - $this->addVariable(_("Order by"), 'sort_by', 'enum', false, false, false, array(array('n.publish' => _("Publish date"), - 'n.id' => _("Id"), - 'l.title' => _("Title"), - 'n.comments' => _("Comments"), - 'n.reads' => _("Reads"), - 'n.attachemt' => _("Attachments")))); - - $this->addVariable(_("Sort order"), 'sort_dir', 'enum', false, false, false, array(array('DESC' => _("Descending"), - 'ASC' => _("Ascending")))); - - $this->addVariable(_("Publish"), 'publish', 'datetime', false, false, false, $GLOBALS['news']->datetimeParams()); - $this->addVariable(_("Unpublish"), 'unpublish', 'datetime', false, false, false, $GLOBALS['news']->datetimeParams()); - $this->addVariable(_("User"), 'user', 'text', false, false, false); - - if ($GLOBALS['registry']->isAdmin()) { - $this->addVariable(_("Editor"), 'editor', 'text', false, false, false); - } - - } - - /** - * Get pager - */ - public function getPager($info, $count, $url) - { - $pager = new Horde_Core_Ui_Pager('news_page', - Horde_Variables::getDefaultVariables(), - array('num' => $count, - 'url' => $url, - 'page_count' => 10, - 'perpage' => $GLOBALS['prefs']->getValue('per_page'))); - - foreach ($info as $key => $value) { - if (substr($key, 0, 1) == '_') { - continue; - } elseif ($key == 'word') { - $pager->preserve($key, substr($value, 1, -1)); - } else { - $pager->preserve($key, $value); - } - } - - return $pager; - } - /** - * Fetch the field values of the submitted form. - * - * @param Horde_Variables $vars A Horde_Variables instance, optional since Horde 3.2. - * @param array $info Array to be filled with the submitted field - * values. - */ - function getInfo($vars, &$info) - { - $this->_getInfoFromVariables($this->getVariables(), $this->_vars, $info); - } - - /** - * Fetch the field values from a given array of variables. - * - * @access private - * - * @param array $variables An array of Horde_Form_Variable objects to - * fetch from. - * @param object $vars The Horde_Variables object. - * @param array $info The array to be filled with the submitted - * field values. - */ - function _getInfoFromVariables($variables, &$vars, &$info) - { - foreach ($variables as $var) { - $value = $var->getValue($vars); - if (empty($value)) { - continue; - } - - if (Horde_Array::getArrayParts($var->getVarName(), $base, $keys)) { - if (!isset($info[$base])) { - $info[$base] = array(); - } - $pointer = &$info[$base]; - while (count($keys)) { - $key = array_shift($keys); - if (!isset($pointer[$key])) { - $pointer[$key] = array(); - } - $pointer = &$pointer[$key]; - } - $var->getInfo($vars, $pointer); - } else { - $var->getInfo($vars, $info[$var->getVarName()]); - } - - } - } - -} diff --git a/news/lib/News.php b/news/lib/News.php deleted file mode 100644 index 2eceb0378..000000000 --- a/news/lib/News.php +++ /dev/null @@ -1,469 +0,0 @@ - - * @package News - */ -class News { - - const UNCONFIRMED = 0; - const CONFIRMED = 1; - const LOCKED = 2; - - const VFS_PATH = '.horde/news'; - - /** - * Returns the current language - * - * @return string The current language. - */ - static public function getLang() - { - global $conf; - - static $lang; - - if ($lang === null) { - $lang = $GLOBALS['registry']->preferredLang(); - if (!empty($conf['attributes']['languages']) && - !in_array($lang, $conf['attributes']['languages'])) { - $lang = $conf['attributes']['languages'][0]; - } - } - - return $lang; - } - - /** - * Returns a flag image for a country. - * - * @param string $lang The language to return the flag for, e.g. 'us'. - */ - static public function getFlag($country) - { - $flag = 'flags/' . strtolower(substr($country, -2)) . '.png'; - return Horde::img($flag, $country); - } - - /** - * Load trackback object - * - * @param array $data Data to pass to the communication - */ - static public function loadTrackback($data = array()) - { - include_once 'Services/Trackback.php'; - if (!class_exists('Services_Trackback')) { - return PEAR::raiseError(_("Services/Trackback is not installed.")); - } - - $trackback_conf = $GLOBALS['conf']['trackback']; - unset($trackback_conf['spamcheck']); - $trackback_conf['httprequest'] = array( - 'allowRedirects' => true, - 'maxRedirects' => 2, - 'useragent' => 'HORDE News' - ); - - return Services_Trackback::create($data, $trackback_conf); - } - - /** - * Return a properly formatted link depending on the global pretty url - * configuration - * - * @param string $controller The controller to generate a URL for. - * @param array $data The data needed to generate the URL. - * @param boolean $full Generate a full URL. - * @param integer $append_session 0 = only if needed, 1 = always, - * -1 = never. - * - * @param string The generated URL - */ - static public function getUrlFor($controller, $data, $full = false, $append_session = 0) - { - switch ($controller) { - - case 'news': - if (empty($GLOBALS['conf']['urls']['pretty'])) { - return Horde_Util::addParameter(Horde::url('news.php', $full, $append_session), 'id', $data); - } else { - return Horde::url('article/' . $data, $full, $append_session); - } - - case 'category': - if (empty($GLOBALS['conf']['urls']['pretty'])) { - return Horde_Util::addParameter(Horde::url('browse.php', $full, $append_session), 'category', $data); - } else { - return Horde::url('category/' . $data, $full, $append_session); - } - - case 'source': - if (empty($GLOBALS['conf']['urls']['pretty'])) { - return Horde_Util::addParameter(Horde::url('browse.php', $full, $append_session), 'source', $data); - } else { - return Horde::url('source/' . $data, $full, $append_session); - } - } - } - - /** - * Template path - * - * @param intiger $id $category id - * @param string $type browse/news - * - * @return string $template template path - */ - static public function getTemplatePath($cid, $type) - { - $template = NEWS_TEMPLATES . '/' . $type . '/'; - if (file_exists($template . $cid)) { - $template .= $cid . '/'; - } - - return $template; - } - - /** - * Format file size - * - * @param int $size File size - * - * @return boolean formatted file_size. - */ - static public function format_filesize($size) - { - $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); - $pass = 0; // set zero, for Bytes - while ($size >= 1024) { - $size /= 1024; - $pass++; - } - - return round($size, 2) . ' ' . $units[$pass]; - } - - /** - * Formats time according to user preferences. - * - * @param int $timestamp Message timestamp. - * - * @return string Formatted date. - */ - static public function dateFormat($timestamp) - { - static $df, $tf; - - if ($df === null) { - $df = $GLOBALS['prefs']->getValue('date_format'); - $tf = $GLOBALS['prefs']->getValue('twentyFour'); - } - - if (is_string($timestamp)) { - $timestamp = strtotime($timestamp); - } - - return strftime($df, $timestamp) - . ' ' - . (date($tf ? 'G:i' : 'g:ia', $timestamp)); - } - - /** - * Format file size - * - * @param int $id News ID - * - * @return boolean formatted file_size. - */ - public function format_attached($id) - { - $files = $GLOBALS['news']->getFiles($id); - if (empty($files)) { - return ''; - } - - if ($GLOBALS['registry']->isAdmin(array('permission' => 'news:admin'))) { - $delete_img = Horde::img('delete.png', _("Delete"), ' style="width: 16px height: 16px"'); - $delete_url = Horde::url('delete_file.php'); - } - - $dowload_img = Horde::img('save.png', _("Dowload"), ' style="width: 16px height: 16px"'); - $dowload_zip = Horde::img('mime/compressed.png', _("Dowload Zip Compressed"), 'style="width: 16px height: 16px"'); - $view_url = Horde::url('files.php'); - - $html = '
'; - $html .= Horde::link(Horde_Util::addParameter($view_url, array('actionID' => 'download_zip_all', 'news_id' => $id)), _("Compress and dowload all files at once")) . $dowload_zip . ' ' . "\n"; - $html .= _("Attached files: ") . '' . "\n"; - - foreach ($files as $file) { - $view_url = Horde_Util::addParameter($view_url, $file); - $html .= ' - ' . "\n"; - $html .= Horde::link(Horde_Util::addParameter($view_url, 'actionID', 'download_zip'), sprintf(_("Compress and dowload %s"), $file['file_name'])) . $dowload_zip . ' ' . "\n"; - $html .= Horde::link(Horde_Util::addParameter($view_url, 'actionID', 'download_file'), sprintf(_("Dowload %s"), $file['file_name'])) . $dowload_img . ' ' . "\n"; - $html .= Horde::link(Horde_Util::addParameter($view_url, 'actionID', 'view_file'), sprintf(_("Preview %s"), $file['file_name']), '', '_file_view'); - $html .= Horde::img($GLOBALS['injector']->getInstance('Horde_Mime_Viewer')->getIcon($file['file_type']), $file['file_name'], 'width="16" height="16"', '') . ' '; - if ($GLOBALS['registry']->isAdmin(array('permission' => 'news:admin'))) { - $html .= Horde::link(Horde_Util::addParameter($delete_url, $file), sprintf(_("Delete %s"), $file['file_name'])) . $delete_img . ' ' . "\n"; - } - $html .= $file['file_name'] . ' ' . "\n"; - $html .= ' (' . self::format_filesize($file['file_size']) . ')'; - $html .= '
' . "\n"; - } - - $html .= '
'; - - return $html; - } - - /** - * Store image - * - * @param $id Image owner record id - * @param $file['file_name'] Horde_Form_Type_image::getInfo() result - * @param $type Image type ('events', 'categories' ...) - * @param $resize Resize the big image? - */ - static public function saveImage($id, $file, $type = 'news', $resize = true) - { - global $conf; - - $vfs = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images'); - $vfspath = self::VFS_PATH . '/images/' . $type; - $vfs_name = $id . '.' . $conf['images']['image_type']; - - $context = array('tmpdir' => Horde::getTempDir()); - if (!empty($conf['image']['convert'])) { - $context['convert'] = $conf['image']['convert']; - $context['identify'] = $conf['image']['identify']; - } - $params = array('type' => $conf['images']['image_type'], - 'context' => $context); - $driver = $conf['image']['driver']; - $img = Horde_Image::factory($driver, $params); - $result = $img->loadFile($file); - - // Store big image for articles - if ($type == 'news') { - - // Store full image - $vfs->writeData($vfspath . '/full/', $vfs_name, $img->raw(), true); - - // Resize big image? - if ($resize) { - $dimensions = $img->getDimensions(); - if ($dimensions instanceof PEAR_Error) { - return $dimensions; - } - - $resize = $img->resize(min($conf['images']['image_width'], $dimensions['width']), - min($conf['images']['image_height'], $dimensions['height'])); - if ($resize instanceof PEAR_Error) { - return $resize; - } - } - - // Store big image - $vfs->writeData($vfspath . '/big/', $vfs_name, $img->raw(), true); - } - - // Resize thumbnail - $dimensions = $img->getDimensions(); - $resize = $img->resize(min($conf['images']['thumbnail_width'], $dimensions['width']), - min($conf['images']['thumbnail_height'], $dimensions['height'])); - if ($resize instanceof PEAR_Error) { - return $resize; - } - - // Trick path for articles - if ($type == 'news') { - $vfspath .= '/small'; - } - - // Store thumbnail - return $vfs->writeData($vfspath, $vfs_name, $img->raw(), true); - } - - /** - * Delete image - * - * @param $id Image id (item id) - */ - static public function deleteImage($id) - { - $vfs = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images'); - $vfs_name = $id . '.' . $GLOBALS['conf']['images']['image_type']; - $vfs->deleteFile(self::VFS_PATH . '/images/news/full', $vfs_name); - $vfs->deleteFile(self::VFS_PATH . '/images/news/small', $vfs_name); - $vfs->deleteFile(self::VFS_PATH . '/images/news/big', $vfs_name); - } - - /** - * Store file - * - * @param $file_id File id - * @param $file_src File path - */ - static public function saveFile($file_id, $file_src) - { - $vfs = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images'); - $vfs->writeData(self::VFS_PATH . '/files/', $file_id, file_get_contents($file_src), true); - } - - /** - * Get file contents - * - * @param $file_id File ID - */ - static public function getFile($file_id) - { - $vfs = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images'); - $vfs->read(self::VFS_PATH . '/files/', $file_id); - } - - /** - * Delete file - * - * @param $id File ID - */ - static public function deleteFile($file_id) - { - $vfs = $GLOBALS['injector']->getInstance('Horde_Vfs')->getVfs('images'); - if ($vfs->exists(self::VFS_PATH . '/files/', $file_id)) { - $vfs->deleteFile(self::VFS_PATH . '/files/', $file_id); - } - } - - /** - * Returns image path - */ - static public function getImageUrl($id, $view = 'small', $type = 'news') - { - if (empty($GLOBALS['conf']['images']['direct'])) { - return Horde_Util::addParameter(Horde::url('view.php'), - array('type' => $type, - 'view' => $view, - 'id' => $id), - null, false); - } else { - return $GLOBALS['conf']['images']['direct'] . - '/' . $type . '/' . $view . '/' . - $id . '.' . $GLOBALS['conf']['images']['image_type']; - } - } - - /** - * Returns gallery images - */ - static public function getGalleyImages($id) - { - $images = $GLOBALS['cache']->get("news_gallery_$id", 0); - if ($images) { - return unserialize($images); - } - - $images = $GLOBALS['registry']->call('images/listImages', array('ansel', $id, Horde_Perms::SHOW, 'thumb')); - $GLOBALS['cache']->set("news_gallery_$id", serialize($images)); - - return $images; - } - - - - /** - * Fomates time accoring to user prefs - * - * @param int $timestamp message timestamp - * - * @return string $date fromatted date - */ - public function datetimeParams() - { - static $params; - - if (!is_array($params)) { - $sql = 'SELECT MIN(YEAR(publish)) FROM ' . $GLOBALS['news']->prefix; - $params = array('start_year' => $GLOBALS['news']->db->getOne($sql), - 'end_year' => date('Y') + 1, - 'picker' => true, - 'format_in' => '%Y-%m-%d %H:%M:%S', - 'format_out' => '%Y-%m-%d %H:%M:%S'); - } - - return $params; - } - - /** - * Get last submitted comments - * - * @param int $limit How many comments to show - */ - static public function getLastComments($limit = 10) - { - $cache_key = 'news_lastcommetns_' . $limit; - $threads = $GLOBALS['cache']->get($cache_key, $GLOBALS['conf']['cache']['default_lifetime']); - if ($threads) { - return unserialize($threads); - } - - global $registry; - - if (!$registry->hasMethod('forums/getForumName')) { - return PEAR::raiseError(_("Comments are not supported.")); - } - - $params = array(0, 'message_timestamp', 1, false, 'news', null, 0, $limit); - $threads = $registry->call('forums/getThreads', $params); - - foreach ($threads as $id => $message) { - try { - $news_id = $registry->call('forums/getForumName', array('news', $message['forum_id'])); - } catch (Horde_Exception $e) { - unset($threads[$id]); - continue; - } - - $threads[$id]['news_id'] = $news_id; - $threads[$id]['read_url'] = self::getUrlFor('news', $news_id, true); - } - - $GLOBALS['cache']->set($cache_key, serialize($threads)); - return $threads; - } - - /** - * Build News's list of menu articles - */ - static public function getMenu() - { - $menu = new Horde_Menu(); - $img_dir = Horde_Themes::img(null, 'horde'); - - if ($GLOBALS['prefs']->getValue('news_layout') != '') { - $menu->add(Horde::url('content.php'), _("Overview"), 'layout.png', $img_dir); - } - $menu->add(Horde::url('browse.php'), _("Archive"), 'info.png', $img_dir); - $menu->add(Horde::url('search.php'), _("Search"), 'search.png', $img_dir); - $menu->add(Horde::url('add.php'), _("Add"), 'edit.png', $img_dir); - - if ($GLOBALS['conf']['attributes']['tags']) { - $menu->add(Horde::url('cloud.php'), _("Tag cloud"), 'colorpicker.png', $img_dir); - } - - if ($GLOBALS['registry']->isAdmin(array('permission' => 'news:admin'))) { - $menu->add(Horde::url('edit.php'), _("Editorship"), 'config.png', $img_dir); - $menu->add(Horde::url('admin/categories/index.php'), _("Administration"), 'administration.png', $img_dir); - } - - return $menu; - } - -} diff --git a/news/lib/Search.php b/news/lib/Search.php deleted file mode 100644 index 2d4e76131..000000000 --- a/news/lib/Search.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @package News - */ -class News_Search extends Horde_Form { - - /** - * Creator - */ - public function __construct($vars) - { - parent::__construct($vars, _("Search"), 'news_search'); - - $this->_submit = _("Search"); - - $this->addVariable(_("Search world"), 'word', 'text', false, false, false); - - $s = array(News::UNCONFIRMED => _("Unconfirmed"), - News::CONFIRMED => _("Confirmed"), - News::LOCKED => _("Locked")); - $this->addVariable(_("Status"), 'status', 'enum', false, false, false, array($s, _("-- select --"))); - - $allowed_cats = $GLOBALS['news_cat']->getAllowed(Horde_Perms::DELETE); - $this->addVariable(_("Category"), 'category', 'enum', false, false, false, array($allowed_cats, _("-- select --"))); - - $sources = $GLOBALS['news']->getSources(); - if (!empty($sources)) { - $this->addVariable(_("Source"), 'source', 'enum', false, false, false, array($sources, _("-- select --"))); - } - - $this->addVariable(_("Order by"), 'sort_by', 'enum', false, false, false, array(array('n.publish' => _("Publish date"), - 'n.id' => _("Id"), - 'l.title' => _("Title"), - 'n.comments' => _("Comments"), - 'n.reads' => _("Reads"), - 'n.attachemt' => _("Attachments")))); - - $this->addVariable(_("Sort order"), 'sort_dir', 'enum', false, false, false, array(array('DESC' => _("Descending"), - 'ASC' => _("Ascending")))); - - $this->addVariable(_("Publish"), 'publish', 'datetime', false, false, false, News::datetimeParams()); - $this->addVariable(_("Unpublish"), 'unpublish', 'datetime', false, false, false, News::datetimeParams()); - $this->addVariable(_("User"), 'user', 'text', false, false, false); - - if ($GLOBALS['registry']->isAdmin()) { - $this->addVariable(_("Editor"), 'editor', 'text', false, false, false); - } - } - - /** - * Get pager - */ - static public function getPager($info, $count, $url) - { - $pager = new Horde_Core_Ui_Pager('news_page', - Horde_Variables::getDefaultVariables(), - array('num' => $count, - 'url' => $url, - 'page_count' => 10, - 'perpage' => $GLOBALS['prefs']->getValue('per_page'))); - - foreach ($info as $key => $value) { - if (substr($key, 0, 1) == '_') { - continue; - } elseif ($key == 'word') { - $pager->preserve($key, substr($value, 1, -1)); - } else { - $pager->preserve($key, $value); - } - } - - return $pager; - } - /** - * Fetch the field values of the submitted form. - * - * @param Horde_Variables $vars A Horde_Variables instance, optional since Horde 3.2. - * @param array $info Array to be filled with the submitted field - * values. - */ - function getInfo($vars, &$info) - { - $this->_getInfoFromVariables($this->getVariables(), $this->_vars, $info); - } - - /** - * Fetch the field values from a given array of variables. - * - * @access private - * - * @param array $variables An array of Horde_Form_Variable objects to - * fetch from. - * @param object $vars The Horde_Variables object. - * @param array $info The array to be filled with the submitted - * field values. - */ - function _getInfoFromVariables($variables, &$vars, &$info) - { - foreach ($variables as $var) { - $value = $var->getValue($vars); - if (empty($value)) { - continue; - } - - if (Horde_Array::getArrayParts($var->getVarName(), $base, $keys)) { - if (!isset($info[$base])) { - $info[$base] = array(); - } - $pointer = &$info[$base]; - while (count($keys)) { - $key = array_shift($keys); - if (!isset($pointer[$key])) { - $pointer[$key] = array(); - } - $pointer = &$pointer[$key]; - } - $var->getInfo($vars, $pointer); - } else { - $var->getInfo($vars, $info[$var->getVarName()]); - } - - } - } - -} diff --git a/news/lib/TagCloud.php b/news/lib/TagCloud.php deleted file mode 100644 index 2bb165211..000000000 --- a/news/lib/TagCloud.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @package News - */ -class News_TagCloud extends Horde_Core_Ui_TagCloud { - - /** - * create a Element of HTML part - * - * @return string a Element of Tag HTML - * @param array $tag - * @param string $type css class of time line param - * @param int $fontsize - */ - protected function _createHTMLTag($tag, $type, $fontsize) - { - return sprintf("%s\n", - $type, - $tag['url'], - htmlspecialchars($tag['name'])); - } - - /** - * wrap div tag - * - * @return string - * @param string $html - */ - protected function _wrapDiv($html) - { - return $html; - } - -} diff --git a/news/lib/View.php b/news/lib/View.php deleted file mode 100644 index 835cfecb7..000000000 --- a/news/lib/View.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @package News - */ -class News_View extends Horde_View { - - /** - * Constructor - */ - public function __construct() - { - /* Set parents defualt data */ - parent::__construct(array('templatePath' => NEWS_TEMPLATES, - 'encoding' => $GLOBALS['registry']->preferredLang())); - } - - /** - * Formats time according to user preferences. - * - * @param int $timestamp Message timestamp. - * - * @return string Formatted date. - */ - public function format_date($timestamp) - { - return strftime($GLOBALS['prefs']->getValue('date_format'), $timestamp); - } - - /** - * Formats time according to user preferences. - * - * @param int $timestamp Message timestamp. - * - * @return string Formatted date. - */ - public function format_datetime($timestamp) - { - return strftime($GLOBALS['prefs']->getValue('date_format'), $timestamp) - . ' ' - . (date($GLOBALS['prefs']->getValue('twentyFour') ? 'G:i' : 'g:ia', $timestamp)); - } - - /** - * Link tags - * - * @param string $tags Video's tags - */ - public function getTagsLinks($tags) - { - if (empty($tags)) { - return ''; - } - - $html = ''; - $search = Horde::url('search.php'); - foreach (explode(' ', $tags) as $tag) { - $html .= '' . $tag . ' '; - } - - return $html; - } -} diff --git a/news/lib/base.php b/news/lib/base.php deleted file mode 100644 index 2d4ff8c60..000000000 --- a/news/lib/base.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @package News - */ - -// Check for a prior definition of HORDE_BASE (perhaps by an -// auto_prepend_file definition for site customization). -if (!defined('HORDE_BASE')) { - define('HORDE_BASE', dirname(__FILE__) . '/../..'); -} - -// Load the Horde Framework core. -require_once HORDE_BASE . '/lib/core.php'; - -// Registry. -$registry = new Horde_Registry(); -try { - $registry->pushApp('news', array('check_perms' => (Horde_Util::nonInputVar('news_authentication') != 'none'), 'logintasks' => true)); -} catch (Horde_Exception $e) { - $registry->authenticateFailure('news', $e); -} -$conf = &$GLOBALS['conf']; -define('NEWS_TEMPLATES', $registry->get('templates')); - -// Define the base file path of News. -if (!defined('NEWS_BASE')) { - define('NEWS_BASE', dirname(__FILE__) . '/..'); -} - -// Cache -$GLOBALS['cache'] = $injector->getInstance('Horde_Cache'); - -// Set up News drivers. -$GLOBALS['news'] = News_Driver::factory(); -$GLOBALS['news_cat'] = new News_Categories(); - -// Start compression. -if (!Horde_Util::nonInputVar('no_compress')) { - Horde::compressOutput(); -} diff --git a/news/locale/.htaccess b/news/locale/.htaccess deleted file mode 100644 index 3a4288278..000000000 --- a/news/locale/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/news/locale/news.pot b/news/locale/news.pot deleted file mode 100644 index 36074a879..000000000 --- a/news/locale/news.pot +++ /dev/null @@ -1,958 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Horde Project -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: dev@lists.horde.org\n" -"POT-Creation-Date: 2010-08-17 17:46+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: templates/edit/info.php:103 -msgid " at " -msgstr "" - -#: news.php:38 templates/edit/info.php:103 -msgid " by " -msgstr "" - -#: content_edit.php:28 -#, php-format -msgid "%s :: Add Content" -msgstr "" - -#: mail.php:48 -#, php-format -msgid "" -"%s would you like to invite you to read the news\n" -" Title: %s\n" -"\n" -" Published: %s \n" -"Link: %s" -msgstr "" - -#: templates/news/news.php:21 -msgid "* Sponsored news" -msgstr "" - -#: add.php:130 add.php:137 add.php:154 lib/Search.php:31 lib/Search.php:34 -#: lib/Search.php:38 lib/Forms/Search.php:28 lib/Forms/Search.php:31 -#: lib/Forms/Search.php:35 -msgid "-- select --" -msgstr "" - -#: templates/edit/header.inc:5 -msgid "Action" -msgstr "" - -#: templates/edit/row.php:20 -msgid "Activate" -msgstr "" - -#: lib/News.php:455 -msgid "Add" -msgstr "" - -#: content.php:26 -msgid "Add Content" -msgstr "" - -#: admin/categories/index.php:40 admin/sources/index.php:42 -msgid "Add New" -msgstr "" - -#: lib/Categories.php:491 lib/Categories.php:505 -msgid "Add New Item" -msgstr "" - -#: admin/sources/edit.php:19 -msgid "Add Source" -msgstr "" - -#: admin/categories/edit.php:18 -msgid "Add category" -msgstr "" - -#: add.php:97 -msgid "Add news" -msgstr "" - -#: templates/news/tools.php:18 -msgid "Add to bookmarks." -msgstr "" - -#: templates/news/tools.php:24 -msgid "Add to notes." -msgstr "" - -#: add.php:153 -msgid "Additional news attributes" -msgstr "" - -#: add.php:218 lib/Application.php:30 -msgid "Admin" -msgstr "" - -#: lib/News.php:463 -msgid "Administration" -msgstr "" - -#: templates/edit/info.php:32 -msgid "Allow comments" -msgstr "" - -#: lib/News.php:453 -msgid "Archive" -msgstr "" - -#: delete_file.php:24 -msgid "Are you sure you want to delete file?" -msgstr "" - -#: delete.php:24 -msgid "Are you sure you want to delete this news?" -msgstr "" - -#: lib/Search.php:49 lib/Forms/Search.php:46 -msgid "Ascending" -msgstr "" - -#: config/prefs.php.dist:40 -msgid "Ascesending" -msgstr "" - -#: lib/News.php:205 -msgid "Attached files: " -msgstr "" - -#: lib/Search.php:46 lib/Forms/Search.php:43 -msgid "Attachments" -msgstr "" - -#: add.php:152 -msgid "Attributes" -msgstr "" - -#: templates/news/info.php:10 -msgid "Besed" -msgstr "" - -#: trackback.php:68 -#, php-format -msgid "Blog entry %s does not exist." -msgstr "" - -#: templates/news/blog.php:3 -msgid "Blogs" -msgstr "" - -#: browse.php:19 search.php:17 -msgid "Browse" -msgstr "" - -#: templates/news/info.php:4 -msgid "By" -msgstr "" - -#: delete_file.php:25 delete.php:25 admin/categories/delete.php:18 -#: admin/sources/delete.php:19 -msgid "Cancel" -msgstr "" - -#: add.php:200 -msgid "Caption" -msgstr "" - -#: admin/tabs.php:23 lib/Application.php:38 lib/Block/categories.php:3 -#: lib/Block/categories.php:21 templates/categories/edit.html:5 -#: templates/categories/index.html:4 templates/categories/delete.html:5 -msgid "Categories" -msgstr "" - -#: templates/menu.inc:4 templates/news/info.php:6 lib/Search.php:34 -#: lib/Forms/Search.php:31 lib/Block/category.php:35 -msgid "Category" -msgstr "" - -#: admin/categories/index.php:25 -msgid "Category Administration" -msgstr "" - -#: admin/categories/delete.php:29 -msgid "Category deleted." -msgstr "" - -#: admin/categories/edit.php:46 -#, php-format -msgid "Category succesfully saved." -msgstr "" - -#: admin/categories/delete.php:27 admin/categories/delete.php:32 -msgid "Category was not deleted." -msgstr "" - -#: templates/browse/row.inc:9 templates/news/info.php:9 -msgid "Chars" -msgstr "" - -#: templates/news/news.php:10 templates/edit/info.php:8 -msgid "Click for full picture" -msgstr "" - -#: templates/browse/row.inc:10 templates/edit/header.inc:13 lib/Search.php:44 -#: lib/Forms/Search.php:41 -msgid "Comments" -msgstr "" - -#: lib/News.php:420 -msgid "Comments are not supported." -msgstr "" - -#: lib/News.php:210 -#, php-format -msgid "Compress and dowload %s" -msgstr "" - -#: lib/News.php:204 -msgid "Compress and dowload all files at once" -msgstr "" - -#: templates/edit/row.php:46 lib/Search.php:29 lib/Forms/Search.php:26 -msgid "Confirmed" -msgstr "" - -#: add.php:125 add.php:148 -msgid "Content" -msgstr "" - -#: templates/reads/header.inc:8 -msgid "Date" -msgstr "" - -#: templates/edit/row.php:17 -msgid "Deactivate" -msgstr "" - -#: templates/edit/row.php:23 admin/categories/index.php:29 -#: admin/categories/index.php:32 admin/sources/index.php:27 -#: admin/sources/index.php:34 lib/News.php:195 -msgid "Delete" -msgstr "" - -#: lib/News.php:215 -#, php-format -msgid "Delete %s" -msgstr "" - -#: add.php:103 add.php:119 -msgid "Delete existing picture" -msgstr "" - -#: templates/edit/info.php:11 -msgid "Delete picture" -msgstr "" - -#: lib/Search.php:48 lib/Forms/Search.php:45 -msgid "Descending" -msgstr "" - -#: config/prefs.php.dist:39 -msgid "Descesending" -msgstr "" - -#: templates/categories/index.php:8 admin/categories/edit.php:32 -msgid "Description" -msgstr "" - -#: diff.php:18 templates/edit/info.php:112 -msgid "Diff" -msgstr "" - -#: add.php:227 -msgid "Disallow comments" -msgstr "" - -#: templates/edit/info.php:11 -msgid "Do you really want to delete this picture?" -msgstr "" - -#: admin/categories/delete.php:17 -msgid "Do you really wont to delete this category?" -msgstr "" - -#: admin/sources/delete.php:18 -msgid "Do you really wont to delete this source?" -msgstr "" - -#: lib/News.php:199 -msgid "Dowload" -msgstr "" - -#: lib/News.php:211 -#, php-format -msgid "Dowload %s" -msgstr "" - -#: lib/News.php:200 -msgid "Dowload Zip Compressed" -msgstr "" - -#: edit.php:146 templates/edit/row.php:6 templates/edit/row.php:7 -#: admin/categories/index.php:27 admin/categories/index.php:34 -#: admin/sources/index.php:25 admin/sources/index.php:36 -msgid "Edit" -msgstr "" - -#: admin/sources/edit.php:19 -msgid "Edit Source" -msgstr "" - -#: admin/categories/edit.php:18 -msgid "Edit category" -msgstr "" - -#: templates/edit/info.php:91 -msgid "Edit history: " -msgstr "" - -#: add.php:557 -msgid "Edit news" -msgstr "" - -#: templates/edit/info.php:36 lib/Search.php:56 lib/Forms/Search.php:53 -msgid "Editor" -msgstr "" - -#: lib/Application.php:33 -msgid "Editors" -msgstr "" - -#: lib/News.php:462 -msgid "Editorship" -msgstr "" - -#: add.php:178 -msgid "Enter gallery ID or upload images below" -msgstr "" - -#: add.php:156 -msgid "Enter news ids separated by commas." -msgstr "" - -#: add.php:146 -msgid "" -"Enter one or more keywords that describe your news. Separate them by spaces." -msgstr "" - -#: add.php:159 -msgid "Enter threads separated by commas." -msgstr "" - -#: delete_file.php:55 -#, php-format -msgid "Error deleteing file \"%s\" from news \"%s\"" -msgstr "" - -#: templates/news/today.php:11 -msgid "Events on this day." -msgstr "" - -#: add.php:212 -msgid "File" -msgstr "" - -#: delete_file.php:74 -#, php-format -msgid "File \"%s\" was deleted from news \"%s\"" -msgstr "" - -#: delete_file.php:81 -#, php-format -msgid "File \"%s\" was not deleted from news \"%s\"" -msgstr "" - -#: add.php:205 add.php:466 -msgid "Files" -msgstr "" - -#: files.php:82 -#, php-format -msgid "FilesOfNews-%s" -msgstr "" - -#: add.php:264 -msgid "Form ID" -msgstr "" - -#: add.php:265 -msgid "Form to" -msgstr "" - -#: templates/news/blog.php:10 -msgid "From: " -msgstr "" - -#: add.php:181 add.php:188 -msgid "Gallery" -msgstr "" - -#: lib/Api.php:50 -#, php-format -msgid "Has commented news \"%s\"" -msgstr "" - -#: lib/Block/most_commented.php:26 lib/Block/most_read.php:26 -msgid "How many days back to check?" -msgstr "" - -#: lib/Block/last_blogs.php:21 lib/Block/most_commented.php:23 -#: lib/Block/most_read.php:23 lib/Block/last.php:25 lib/Block/category.php:32 -msgid "How many news to display?" -msgstr "" - -#: config/prefs.php.dist:20 -msgid "How many news to show per page" -msgstr "" - -#: config/prefs.php.dist:10 -msgid "How to preview news" -msgstr "" - -#: templates/reads/header.inc:7 -msgid "IP" -msgstr "" - -#: templates/categories/index.php:5 templates/sources/index.php:5 -#: lib/Search.php:42 lib/Forms/Search.php:39 config/prefs.php.dist:29 -msgid "Id" -msgstr "" - -#: admin/categories/edit.php:38 admin/sources/edit.php:37 -msgid "Image" -msgstr "" - -#: add.php:162 -msgid "Images" -msgstr "" - -#: add.php:197 -msgid "" -"Images will be added to a gallery linked with this article. You can edit and " -"manage images in gallery." -msgstr "" - -#: templates/edit/row.php:9 templates/edit/row.php:10 -msgid "Info" -msgstr "" - -#: templates/edit/info.php:100 -msgid "Insert" -msgstr "" - -#: templates/common-header.inc:27 rss/index.php:43 rss/comments.php:20 -#: lib/Block/last_comments.php:3 lib/Block/last_comments.php:31 -msgid "Last comments" -msgstr "" - -#: lib/Block/my_comments.php:3 -msgid "Last comments on my news" -msgstr "" - -#: lib/Block/most_commented.php:3 lib/Block/most_commented.php:17 -msgid "Last most commented news" -msgstr "" - -#: lib/Block/most_read.php:3 lib/Block/most_read.php:17 -msgid "Last most read news" -msgstr "" - -#: templates/common-header.inc:26 rss/index.php:37 rss/news.php:32 -#: lib/Block/last.php:3 lib/Block/last.php:17 -#, php-format -msgid "Last news" -msgstr "" - -#: lib/Block/last_blogs.php:15 -msgid "Last news blog" -msgstr "" - -#: lib/Block/last_blogs.php:3 -msgid "Last news blogged" -msgstr "" - -#: lib/Block/category.php:21 lib/Block/category.php:22 -#, php-format -msgid "Last news in %s" -msgstr "" - -#: lib/Block/category.php:3 -msgid "Last news in category" -msgstr "" - -#: note.php:27 pdf.php:56 -msgid "Link" -msgstr "" - -#: templates/edit/row.php:30 -msgid "Lock" -msgstr "" - -#: templates/edit/row.php:50 lib/Search.php:30 lib/Forms/Search.php:27 -msgid "Locked" -msgstr "" - -#: add.php:84 -#, php-format -msgid "Maximum file size: %s; with a total of: %s" -msgstr "" - -#: templates/categories/index.php:6 templates/sources/index.php:6 -#: admin/categories/edit.php:31 admin/sources/edit.php:32 -msgid "Name" -msgstr "" - -#: templates/reads/header.inc:5 -msgid "News" -msgstr "" - -#: edit.php:56 edit.php:70 edit.php:81 edit.php:92 edit.php:103 edit.php:142 -#, php-format -msgid "News \"%s\" (%s): %s" -msgstr "" - -#: reads.php:30 -#, php-format -msgid "News %s" -msgstr "" - -#: delete.php:81 delete.php:85 -#, php-format -msgid "News %s: %s" -msgstr "" - -#: add.php:546 -msgid "" -"News added. The editors will check the entry and confirm it if they find it " -"suitable." -msgstr "" - -#: add.php:219 -msgid "News administrator options" -msgstr "" - -#: add.php:126 -msgid "News content" -msgstr "" - -#: templates/news/info.php:3 -msgid "News data" -msgstr "" - -#: add.php:163 -msgid "News images" -msgstr "" - -#: templates/news/today.php:5 -msgid "News of this day." -msgstr "" - -#: add.php:548 -msgid "News published." -msgstr "" - -#: mail.php:57 -#, php-format -msgid "News succesfully send to %s" -msgstr "" - -#: note.php:38 -msgid "News sucessfuly added to you notes." -msgstr "" - -#: add.php:550 -msgid "News updated." -msgstr "" - -#: templates/edit/info.php:32 -msgid "No" -msgstr "" - -#: diff.php:59 -msgid "No change." -msgstr "" - -#: mail.php:38 -msgid "No mail entered." -msgstr "" - -#: lib/Block/my_comments.php:17 lib/Block/last_comments.php:19 -msgid "Number of comments to display" -msgstr "" - -#: note.php:26 pdf.php:55 templates/news/info.php:5 -msgid "On" -msgstr "" - -#: templates/news/today.php:3 -msgid "On this day" -msgstr "" - -#: delete_file.php:19 delete.php:19 -msgid "Only admin can delete a news." -msgstr "" - -#: add.php:92 -msgid "Only authenticated users can post news." -msgstr "" - -#: mail.php:33 -msgid "Only authenticated users can send mails." -msgstr "" - -#: lib/Search.php:41 lib/Forms/Search.php:38 -msgid "Order by" -msgstr "" - -#: lib/News.php:451 -msgid "Overview" -msgstr "" - -#: templates/news/tools.php:9 -msgid "PDF" -msgstr "" - -#: templates/categories/index.php:7 admin/categories/edit.php:35 -msgid "Parent" -msgstr "" - -#: add.php:156 templates/news/parents.php:5 templates/edit/info.php:44 -msgid "Parents" -msgstr "" - -#: add.php:166 add.php:199 -msgid "Picture" -msgstr "" - -#: add.php:170 -msgid "Picture comment" -msgstr "" - -#: lib/Block/jonah.php:4 lib/Block/jonah.php:24 -msgid "Press overview" -msgstr "" - -#: config/prefs.php.dist:9 -msgid "Preview" -msgstr "" - -#: lib/News.php:212 -#, php-format -msgid "Preview %s" -msgstr "" - -#: add.php:130 templates/edit/info.php:18 templates/edit/info.php:20 -msgid "Primary category" -msgstr "" - -#: templates/news/tools.php:6 -msgid "Printer firendly" -msgstr "" - -#: add.php:128 lib/Search.php:51 lib/Forms/Search.php:48 -msgid "Publish" -msgstr "" - -#: templates/edit/header.inc:8 -msgid "Publish at" -msgstr "" - -#: lib/Search.php:41 lib/Forms/Search.php:38 config/prefs.php.dist:28 -msgid "Publish date" -msgstr "" - -#: templates/news/parents.php:8 templates/edit/row.php:54 -msgid "Read" -msgstr "" - -#: templates/edit/header.inc:10 lib/Search.php:45 lib/Forms/Search.php:42 -msgid "Reads" -msgstr "" - -#: delete_file.php:25 delete_file.php:51 delete.php:25 delete.php:36 -#: admin/categories/delete.php:18 admin/categories/delete.php:24 -#: admin/sources/delete.php:19 admin/sources/delete.php:25 -msgid "Remove" -msgstr "" - -#: templates/edit/info.php:109 -msgid "Renew" -msgstr "" - -#: add.php:119 add.php:121 add.php:591 -msgid "Reset" -msgstr "" - -#: admin/categories/edit.php:36 admin/sources/edit.php:35 -msgid "Resize Image" -msgstr "" - -#: add.php:121 -msgid "Save" -msgstr "" - -#: lib/News.php:454 lib/Search.php:22 lib/Search.php:24 -#: lib/Forms/Search.php:19 lib/Forms/Search.php:21 -msgid "Search" -msgstr "" - -#: lib/Search.php:26 lib/Forms/Search.php:23 -msgid "Search world" -msgstr "" - -#: add.php:154 templates/edit/info.php:24 -msgid "Secondary category" -msgstr "" - -#: lib/Categories.php:498 -msgid "Select Category" -msgstr "" - -#: lib/Block/jonah.php:35 -msgid "Select a feed." -msgstr "" - -#: add.php:249 templates/edit/info.php:58 -msgid "Selling item" -msgstr "" - -#: templates/news/mail.php:2 -msgid "Send by mail" -msgstr "" - -#: lib/News.php:65 -msgid "Services/Trackback is not installed." -msgstr "" - -#: config/prefs.php.dist:11 -msgid "Set news previerw paramaters" -msgstr "" - -#: lib/Block/last.php:28 -msgid "Skip category" -msgstr "" - -#: config/prefs.php.dist:31 config/prefs.php.dist:41 -msgid "Sort news by" -msgstr "" - -#: add.php:155 templates/edit/info.php:40 lib/Search.php:48 -#: lib/Forms/Search.php:45 -msgid "Sort order" -msgstr "" - -#: add.php:137 templates/edit/info.php:48 lib/Search.php:38 -#: lib/Forms/Search.php:35 -msgid "Source" -msgstr "" - -#: admin/sources/delete.php:30 -msgid "Source deleted." -msgstr "" - -#: add.php:139 templates/edit/info.php:52 -msgid "Source link" -msgstr "" - -#: templates/news/info.php:18 -msgid "Source media" -msgstr "" - -#: templates/news/info.php:13 -msgid "Source news" -msgstr "" - -#: admin/sources/edit.php:45 -msgid "Source saved succesfully." -msgstr "" - -#: admin/sources/delete.php:28 admin/sources/delete.php:33 -msgid "Source was not deleted." -msgstr "" - -#: admin/tabs.php:22 lib/Block/sources.php:3 lib/Block/sources.php:21 -msgid "Sources" -msgstr "" - -#: admin/sources/index.php:17 -msgid "Sources Administration" -msgstr "" - -#: add.php:222 -msgid "Sponsored" -msgstr "" - -#: templates/edit/header.inc:6 lib/Search.php:31 lib/Forms/Search.php:28 -msgid "Status" -msgstr "" - -#: lib/News.php:458 -msgid "Tag cloud" -msgstr "" - -#: add.php:146 lib/Block/tags_cloud.php:3 lib/Block/tags_cloud.php:24 -msgid "Tags" -msgstr "" - -#: templates/news/blog.php:7 -msgid "Talkbacks to this article:" -msgstr "" - -#: templates/news/ulaform.php:13 -msgid "Thanks" -msgstr "" - -#: templates/block/news.php:18 templates/block/titles.php:20 -msgid "There are no news to display." -msgstr "" - -#: lib/Driver/sql.php:85 -#, php-format -msgid "There requested news %s don't exist." -msgstr "" - -#: news.php:32 -msgid "There requested version don't exist." -msgstr "" - -#: add.php:443 -msgid "There was an error creating gallery: " -msgstr "" - -#: add.php:457 -msgid "There was an error with the uploaded image: " -msgstr "" - -#: add.php:159 templates/news/threads.php:6 -#, php-format -msgid "Threads in %s" -msgstr "" - -#: add.php:144 templates/edit/header.inc:7 lib/Search.php:43 -#: lib/Forms/Search.php:40 lib/Block/my_comments.php:53 -#: config/prefs.php.dist:30 -msgid "Title" -msgstr "" - -#: templates/news/tools.php:3 -msgid "Tools" -msgstr "" - -#: templates/news/blog.php:22 -msgid "Trackback this blog on this site." -msgstr "" - -#: lib/Driver/sql.php:222 -#, php-format -msgid "URL already trackbacked: %s" -msgstr "" - -#: templates/edit/row.php:42 lib/Search.php:28 lib/Forms/Search.php:25 -msgid "Unconfirmed" -msgstr "" - -#: templates/edit/row.php:27 -msgid "Unlock" -msgstr "" - -#: lib/Search.php:52 lib/Forms/Search.php:49 -msgid "Unpublish" -msgstr "" - -#: templates/edit/info.php:28 -msgid "Unpublish date" -msgstr "" - -#: add.php:119 add.php:591 templates/edit/info.php:97 -msgid "Update" -msgstr "" - -#: templates/sources/index.php:7 admin/sources/edit.php:33 -msgid "Url" -msgstr "" - -#: templates/news/blog.php:16 -msgid "Use the following link to trackback from your own site: " -msgstr "" - -#: templates/reads/header.inc:6 templates/edit/header.inc:9 lib/Search.php:53 -#: lib/Forms/Search.php:50 lib/Block/my_comments.php:54 -msgid "User" -msgstr "" - -#: templates/edit/info.php:106 -msgid "View" -msgstr "" - -#: admin/sources/index.php:32 -msgid "View articles" -msgstr "" - -#: admin/sources/index.php:29 -msgid "View items" -msgstr "" - -#: templates/edit/info.php:32 -msgid "Yes" -msgstr "" - -#: admin/tabs.php:15 -msgid "You are not authorised for this action." -msgstr "" - -#: mail.php:44 -msgid "You have no email set." -msgstr "" - -#: edit.php:21 -msgid "You have not editor permission on any category." -msgstr "" - -#: edit.php:81 -msgid "activated" -msgstr "" - -#: edit.php:70 -msgid "deactivated" -msgstr "" - -#: delete.php:81 -msgid "deleted" -msgstr "" - -#: edit.php:92 -msgid "locked" -msgstr "" - -#: delete.php:85 -msgid "not deleted" -msgstr "" - -#: edit.php:56 -msgid "picture deleted" -msgstr "" - -#: edit.php:142 -msgid "renewed" -msgstr "" - -#: edit.php:103 -msgid "unlocked" -msgstr "" diff --git a/news/locale/sl/LC_MESSAGES/news.mo b/news/locale/sl/LC_MESSAGES/news.mo deleted file mode 100755 index dcfbe4ba2940b7c03f8d3a4a0753db53d7d6eb05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137811 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 z 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, 2007, 2008. -msgid "" -msgstr "" -"Project-Id-Version: sl_SI\n" -"Report-Msgid-Bugs-To: dev@lists.horde.org\n" -"POT-Creation-Date: 2009-01-21 01:31+0100\n" -"PO-Revision-Date: 2008-01-15 14:13+0100\n" -"Last-Translator: Marko Milost \n" -"Language-Team: Slovene \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=3;\n" - -#: templates/edit/info.php:91 -msgid " at " -msgstr " ob " - -#: templates/edit/info.php:91 -msgid " by " -msgstr " od " - -#: content_edit.php:26 -#, php-format -msgid "%s :: Add Content" -msgstr "%s :: Dodaj vsebino" - -#: mail.php:46 -#, php-format -msgid "" -"%s would you like to invite you to read the news\n" -" Title: %s\n" -"\n" -" Published: %s \n" -"Link: %s" -msgstr "" -"%s vas vabi, da si preberete to novico\n" -"\n" -" Naslov: %s\n" -" Objavljeno: %s\n" -" Povezava: %s" - -#: templates/news/news.php:18 -msgid "* Sponsored news" -msgstr "* Komercialna objava" - -#: add.php:129 add.php:136 add.php:153 lib/Forms/Search.php:31 -#: lib/Forms/Search.php:34 lib/Forms/Search.php:38 -msgid "-- select --" -msgstr "-- izberi --" - -#: templates/edit/header.inc:5 -msgid "Action" -msgstr "Ukaz" - -#: templates/edit/row.php:20 -msgid "Activate" -msgstr "Aktiviraj" - -#: lib/News.php:1123 -msgid "Add" -msgstr "Vpis" - -#: content.php:24 -msgid "Add Content" -msgstr "Dodaj vsebino" - -#: admin/categories/index.php:40 admin/sources/index.php:42 -msgid "Add New" -msgstr "Dodaj novo" - -#: lib/Categories.php:471 lib/Categories.php:485 -msgid "Add New Item" -msgstr "Dodaj novo" - -#: admin/sources/edit.php:19 -msgid "Add Source" -msgstr "Dodaj vir" - -#: admin/categories/edit.php:18 -msgid "Add category" -msgstr "Dodaj kategorije" - -#: add.php:95 -msgid "Add news" -msgstr "Dodaj novice" - -#: templates/news/tools.php:18 -msgid "Add to bookmarks." -msgstr "Dodaj med priljubljene" - -#: templates/news/tools.php:24 -msgid "Add to notes." -msgstr "Dodaj med zapiske" - -#: add.php:152 -msgid "Additional news attributes" -msgstr "Dodatne lastnosti novice" - -#: add.php:218 lib/api.php:49 -msgid "Admin" -msgstr "Administracija" - -#: lib/News.php:1131 -msgid "Administration" -msgstr "Administracija" - -#: templates/edit/info.php:21 -msgid "Allow comments" -msgstr "Dovoli komentarje" - -#: lib/News.php:1121 -msgid "Archive" -msgstr "Arhiv" - -#: delete_file.php:22 -msgid "Are you sure you want to delete file?" -msgstr "Resnično želite to datoteko?" - -#: delete.php:22 -msgid "Are you sure you want to delete this news?" -msgstr "Resnično želite izbrisati to novico?" - -#: lib/Forms/Search.php:49 -msgid "Ascending" -msgstr "Naraščajoče" - -#: config/prefs.php.dist:40 -msgid "Ascesending" -msgstr "Naraščajoče" - -#: lib/News.php:216 -msgid "Attached files: " -msgstr "Pripete datoteke: " - -#: edit.php:44 -msgid "Attachment deleted" -msgstr "Pripeta datoteka je bila izbrisana" - -#: lib/Forms/Search.php:46 -msgid "Attachments" -msgstr "Pripete datoteke" - -#: add.php:151 -msgid "Attributes" -msgstr "Lastnosti" - -#: templates/news/info.php:10 -msgid "Besed" -msgstr "Besed" - -#: trackback.php:65 -#, php-format -msgid "Blog entry %s does not exist." -msgstr "Blog vpis %s ne obstaja." - -#: templates/news/blog.php:3 -msgid "Blogs" -msgstr "Blogi" - -#: browse.php:16 search.php:16 -msgid "Browse" -msgstr "Prebrskaj" - -#: templates/news/info.php:4 -msgid "By" -msgstr "Od" - -#: delete_file.php:23 delete.php:23 admin/categories/delete.php:18 -#: admin/sources/delete.php:19 -msgid "Cancel" -msgstr "Prekliči" - -#: files.php:52 -#, php-format -msgid "Cannot read file %s" -msgstr "Ne morem prebrati datoteke %s" - -#: add.php:199 -msgid "Caption" -msgstr "Komentar k sliki" - -#: admin/tabs.php:25 lib/api.php:57 lib/Block/categories.php:3 -#: lib/Block/categories.php:21 -msgid "Categories" -msgstr "Kategorije" - -#: templates/menu.inc:4 templates/news/info.php:6 lib/Forms/Search.php:34 -#: lib/Block/category.php:35 -msgid "Category" -msgstr "Kategorija" - -#: admin/categories/index.php:25 -msgid "Category Administration" -msgstr "Urejanje kategorij" - -#: admin/categories/delete.php:29 -msgid "Category deleted." -msgstr "Kategorija je bila izbrisana." - -#: admin/categories/edit.php:46 -#, php-format -msgid "Category succesfully saved." -msgstr "Kategorija je bila uspešno shranjena." - -#: admin/categories/delete.php:27 admin/categories/delete.php:32 -msgid "Category was not deleted." -msgstr "Kategorija ni bila izbrisana." - -#: templates/browse/row.inc:9 templates/news/info.php:9 -msgid "Chars" -msgstr "Znakov" - -#: templates/browse/row.inc:10 templates/edit/header.inc:13 -#: lib/Forms/Search.php:44 -msgid "Comments" -msgstr "Komentarjev" - -#: lib/News.php:487 -msgid "Comments are not supported." -msgstr "Komentarji niso podprti." - -#: lib/News.php:222 -#, php-format -msgid "Compress and dowload %s" -msgstr "Kompresiraj in prenesi datoteko %s" - -#: lib/News.php:215 -msgid "Compress and dowload all files at once" -msgstr "Kompresiraj in prenesi vse datoteke naenkrat" - -#: templates/edit/row.php:46 lib/Forms/Search.php:29 -msgid "Confirmed" -msgstr "Potrjena" - -#: add.php:124 add.php:147 -msgid "Content" -msgstr "Vsebina" - -#: templates/reads/header.inc:8 -msgid "Date" -msgstr "Datum" - -#: templates/edit/row.php:17 -msgid "Deactivate" -msgstr "Deaktiviraj" - -#: templates/edit/row.php:23 admin/categories/index.php:29 -#: admin/categories/index.php:32 admin/sources/index.php:27 -#: admin/sources/index.php:34 lib/News.php:206 -msgid "Delete" -msgstr "Izbriši" - -#: lib/News.php:227 -#, php-format -msgid "Delete %s" -msgstr "Izbriši %s" - -#: add.php:101 add.php:118 -msgid "Delete existing picture" -msgstr "Zbriši obstoječo sliko" - -#: lib/Forms/Search.php:48 -msgid "Descending" -msgstr "Padajoče" - -#: config/prefs.php.dist:39 -msgid "Descesending" -msgstr "Padajoče" - -#: templates/categories/index.php:8 admin/categories/edit.php:32 -msgid "Description" -msgstr "Opis" - -#: diff.php:14 templates/edit/info.php:100 -msgid "Diff" -msgstr "Razlike" - -#: add.php:227 -msgid "Disallow comments" -msgstr "Ne dovoli komentarjev" - -#: admin/categories/delete.php:17 -msgid "Do you really wont to delete this category?" -msgstr "Resnično želite izbrisati izbrano kategorijo?" - -#: admin/sources/delete.php:18 -msgid "Do you really wont to delete this source?" -msgstr "Resnično želite izbrisati ta vir?" - -#: lib/News.php:210 -msgid "Dowload" -msgstr "Prenesi" - -#: lib/News.php:223 -#, php-format -msgid "Dowload %s" -msgstr "Prenesi datoteko %s" - -#: lib/News.php:211 -msgid "Dowload Zip Compressed" -msgstr "Presnemi Zip kompresirano datoteko" - -#: edit.php:116 templates/edit/row.php:6 templates/edit/row.php:7 -#: admin/categories/index.php:27 admin/categories/index.php:34 -#: admin/sources/index.php:25 admin/sources/index.php:36 -msgid "Edit" -msgstr "Uredi" - -#: admin/sources/edit.php:19 -msgid "Edit Source" -msgstr "Uredi vir" - -#: admin/categories/edit.php:18 -msgid "Edit category" -msgstr "Uredi kategoijo" - -#: templates/edit/info.php:80 -msgid "Edit history: " -msgstr "Zgodovina urejanja:" - -#: add.php:542 -msgid "Edit news" -msgstr "Uredi novico" - -#: templates/edit/info.php:25 lib/Forms/Search.php:56 -msgid "Editor" -msgstr "Urednik" - -#: lib/api.php:52 -msgid "Editors" -msgstr "Uredniki" - -#: lib/News.php:1130 -msgid "Editorship" -msgstr "Uredništvo" - -#: add.php:177 -msgid "Enter gallery ID or upload images below" -msgstr "Vnesite ID galerija ali naložite slike" - -#: add.php:155 -msgid "Enter news ids separated by commas." -msgstr "Vnesi id-je novic ločene z vejico." - -#: add.php:145 -msgid "" -"Enter one or more keywords that describe your news. Separate them by spaces." -msgstr "Vnesite eno ali več besed ločenih s presledki." - -#: add.php:158 -msgid "Enter threads separated by commas." -msgstr "Vnesi id-je debat ločene z vejico." - -#: delete_file.php:44 -#, php-format -msgid "Error deleteing file \"%s\" from news \"%s\"" -msgstr "Napaka pri brisanju datoteke \"%s\" z novice \"%s\"" - -#: templates/news/today.php:11 -msgid "Events on this day." -msgstr "Dogodki tega dne" - -#: add.php:211 -msgid "File" -msgstr "Datoteka" - -#: delete_file.php:49 -#, php-format -msgid "File \"%s\" was deleted from news \"%s\"" -msgstr "Datoteke \"%s\" je bila odstranjena od novice \"%s\"" - -#: delete_file.php:53 -#, php-format -msgid "File \"%s\" was not deleted from news \"%s\"" -msgstr "Datoteke \"%s\" ni bila odstranjena od novice \"%s\"" - -#: add.php:204 add.php:458 -msgid "Files" -msgstr "Datoteke" - -#: files.php:60 -#, php-format -msgid "FilesOfNews-%s" -msgstr "DatotekeNovice-%s" - -#: add.php:258 -msgid "Form ID" -msgstr "Formular" - -#: add.php:259 -msgid "Form to" -msgstr "Veljavnost formularja " - -#: templates/news/blog.php:10 -msgid "From: " -msgstr "Od: " - -#: add.php:180 add.php:187 -msgid "Gallery" -msgstr "Galerija" - -#: lib/api.php:101 -#, php-format -msgid "Has commented news \"%s\"" -msgstr "Je komentiral novico \"%s\"" - -#: lib/Block/most_commented.php:26 lib/Block/most_read.php:26 -msgid "How many days back to check?" -msgstr "Koliko dni stare novice naj pregledam?" - -#: lib/Block/last_blogs.php:23 lib/Block/most_commented.php:23 -#: lib/Block/most_read.php:23 lib/Block/last.php:25 lib/Block/category.php:32 -msgid "How many news to display?" -msgstr "Koliko novic naj pikažem?" - -#: config/prefs.php.dist:20 -msgid "How many news to show per page" -msgstr "Koliko novic naj pikažem na stran?" - -#: config/prefs.php.dist:10 -msgid "How to preview news" -msgstr "Kako naj prikažem novice" - -#: templates/reads/header.inc:7 -msgid "IP" -msgstr "ID" - -#: templates/categories/index.php:5 templates/sources/index.php:5 -#: lib/Forms/Search.php:42 config/prefs.php.dist:29 -msgid "Id" -msgstr "Id" - -#: admin/categories/edit.php:38 admin/sources/edit.php:37 -msgid "Image" -msgstr "Slika" - -#: add.php:161 -msgid "Images" -msgstr "Slike" - -#: add.php:196 -msgid "" -"Images will be added to a gallery linked with this article. You can edit and " -"manage images in gallery." -msgstr "" -"Slike bodo naložene v galerijo, ki bo povezana z člankom. Slike lahko " -"urajate v galeriji" - -#: templates/edit/row.php:9 templates/edit/row.php:10 -msgid "Info" -msgstr "Info" - -#: templates/edit/info.php:88 -msgid "Insert" -msgstr "Dodana" - -#: templates/common-header.inc:27 rss/index.php:44 rss/comments.php:22 -#: lib/Block/last_comments.php:3 lib/Block/last_comments.php:31 -msgid "Last comments" -msgstr "Zadnji komentarji" - -#: lib/Block/my_comments.php:3 -msgid "Last comments on my news" -msgstr "Zadnji komentarji na moje novice" - -#: lib/Block/most_commented.php:3 lib/Block/most_commented.php:17 -msgid "Last most commented news" -msgstr "Zadnje najbolj komentirane" - -#: lib/Block/most_read.php:3 lib/Block/most_read.php:17 -msgid "Last most read news" -msgstr "Zadnje najbolj brane" - -#: templates/common-header.inc:26 rss/index.php:38 rss/news.php:33 -#: lib/Block/last.php:3 lib/Block/last.php:17 -#, php-format -msgid "Last news" -msgstr "Zadnje novice" - -#: lib/Block/last_blogs.php:17 -msgid "Last news blog" -msgstr "Zadnje novice z blogi" - -#: lib/Block/last_blogs.php:3 -msgid "Last news blogged" -msgstr "Zadnje novice z blogi" - -#: lib/Block/category.php:21 lib/Block/category.php:22 -#, php-format -msgid "Last news in %s" -msgstr "Zadnje novice v %s" - -#: lib/Block/category.php:3 -msgid "Last news in category" -msgstr "Zadnje novice v kategoriji" - -#: note.php:24 pdf.php:51 -msgid "Link" -msgstr "Povezava" - -#: templates/edit/row.php:30 -msgid "Lock" -msgstr "Zakleni" - -#: templates/edit/row.php:50 lib/Forms/Search.php:30 -msgid "Locked" -msgstr "Zaklenjena" - -#: add.php:82 -#, php-format -msgid "Maximum file size: %s; with a total of: %s" -msgstr "Največja velikost datoteke: %s; skupno: %s" - -#: templates/categories/index.php:6 templates/sources/index.php:6 -#: admin/categories/edit.php:31 admin/sources/edit.php:32 -msgid "Name" -msgstr "Ime" - -#: templates/reads/header.inc:5 -msgid "News" -msgstr "Novica" - -#: reads.php:28 -#, php-format -msgid "News %s" -msgstr "Novica %s" - -#: edit.php:44 edit.php:52 edit.php:60 edit.php:68 edit.php:76 edit.php:109 -#: delete.php:73 delete.php:75 -#, php-format -msgid "News %s: %s" -msgstr "Novica %s: %s" - -#: add.php:530 -msgid "" -"News added. The editors will check the entry and confirm it if they find it " -"suitable." -msgstr "" -"Novica je bila vpisana. Uredniki bodo pregledali vaš vpis in ga potrdili, če " -"je le-ta primeren za objavo pri nas." - -#: add.php:219 -msgid "News administrator options" -msgstr "Adminstratorske lastnosti" - -#: add.php:125 -msgid "News content" -msgstr "Vsebina novice" - -#: templates/news/info.php:3 -msgid "News data" -msgstr "O novici" - -#: add.php:162 -msgid "News images" -msgstr "Slike k novici" - -#: templates/news/today.php:5 -msgid "News of this day." -msgstr "Novice tega dne" - -#: add.php:532 -msgid "News published." -msgstr "Novica objavljena." - -#: mail.php:57 -#, php-format -msgid "News succesfully send to %s" -msgstr "Novice je bila uspešno poslana na %s." - -#: note.php:40 -msgid "News sucessfuly added to you notes." -msgstr "Novica je bila uspešno dodana med vaše zapiske" - -#: add.php:534 -msgid "News updated." -msgstr "Novica osvežena." - -#: templates/edit/info.php:21 -msgid "No" -msgstr "Št." - -#: diff.php:55 -msgid "No change." -msgstr "Ni spremembe." - -#: mail.php:36 -msgid "No mail entered." -msgstr "Pozabili ste vnesti email." - -#: lib/Block/my_comments.php:19 lib/Block/last_comments.php:19 -msgid "Number of comments to display" -msgstr "Število komentarjev" - -#: note.php:23 pdf.php:50 templates/news/info.php:5 -msgid "On" -msgstr "Objavljena" - -#: templates/news/today.php:3 -msgid "On this day" -msgstr "Na današnji dan" - -#: delete_file.php:16 delete.php:16 -msgid "Only admin can delete a news." -msgstr "Samo administratorji lahko brišejo novice." - -#: add.php:90 -msgid "Only authenticated users can post news." -msgstr "Samo ragistrirani uporabniki lahko vpisujejo novice." - -#: mail.php:31 -msgid "Only authenticated users can send mails." -msgstr "Samo ragistrirani uporabniki lahko pošiljajo novice." - -#: lib/Forms/Search.php:41 -msgid "Order by" -msgstr "Razvrsti po" - -#: lib/News.php:1119 -msgid "Overview" -msgstr "Pregled" - -#: templates/news/tools.php:9 -msgid "PDF" -msgstr "PDF" - -#: templates/categories/index.php:7 admin/categories/edit.php:35 -msgid "Parent" -msgstr "Sorodne" - -#: add.php:155 templates/news/parents.php:5 templates/edit/info.php:33 -msgid "Parents" -msgstr "Sorodne novice" - -#: add.php:165 add.php:198 -msgid "Picture" -msgstr "Slika" - -#: add.php:169 -msgid "Picture comment" -msgstr "Komentar k sliki" - -#: lib/Block/jonah.php:4 lib/Block/jonah.php:24 -msgid "Press overview" -msgstr "Pregled tiska" - -#: config/prefs.php.dist:9 -msgid "Preview" -msgstr "Pregled %s" - -#: lib/News.php:224 -#, php-format -msgid "Preview %s" -msgstr "Pregled %s" - -#: add.php:129 templates/edit/info.php:10 -msgid "Primary category" -msgstr "Primarna kategorija" - -#: templates/news/tools.php:6 -msgid "Printer firendly" -msgstr "Tiskanju prijazen izpis" - -#: add.php:127 lib/Forms/Search.php:51 -msgid "Publish" -msgstr "Objavi ob" - -#: templates/edit/header.inc:8 -msgid "Publish at" -msgstr "Objavi ob" - -#: lib/Forms/Search.php:41 config/prefs.php.dist:28 -msgid "Publish date" -msgstr "Objavi ob" - -#: templates/news/parents.php:8 templates/edit/row.php:54 -msgid "Read" -msgstr "Preberi" - -#: templates/edit/header.inc:10 lib/Forms/Search.php:45 -msgid "Reads" -msgstr "Branj" - -#: delete_file.php:23 delete_file.php:41 delete.php:23 delete.php:34 -#: admin/categories/delete.php:18 admin/categories/delete.php:24 -#: admin/sources/delete.php:19 admin/sources/delete.php:25 -msgid "Remove" -msgstr "Odstrani" - -#: templates/edit/info.php:97 -msgid "Renew" -msgstr "Obnovi" - -#: add.php:118 add.php:120 add.php:577 -msgid "Reset" -msgstr "Povrni" - -#: admin/categories/edit.php:36 admin/sources/edit.php:35 -msgid "Resize Image" -msgstr "Spremeni velikost slike" - -#: add.php:120 -msgid "Save" -msgstr "Shrani" - -#: lib/News.php:1122 lib/Forms/Search.php:22 lib/Forms/Search.php:24 -msgid "Search" -msgstr "Najdi" - -#: lib/Forms/Search.php:26 -msgid "Search world" -msgstr "Iskana beseda" - -#: add.php:153 templates/edit/info.php:13 -msgid "Secondary category" -msgstr "Pomožna kategorija" - -#: lib/Categories.php:478 -msgid "Select Category" -msgstr "Izberite kategorijo" - -#: lib/Block/jonah.php:35 -msgid "Select a feed." -msgstr "Izberite vir." - -#: add.php:247 templates/edit/info.php:47 -msgid "Selling item" -msgstr "Prodajani artikel" - -#: templates/news/mail.php:2 -msgid "Send by mail" -msgstr "Pošlji po emailu" - -#: lib/News.php:100 -msgid "Services/Trackback is not installed." -msgstr "Services/Trackback ni nameščen." - -#: config/prefs.php.dist:11 -msgid "Set news previerw paramaters" -msgstr "Nastavitve prikazovanja novic" - -#: lib/Block/last.php:28 -msgid "Skip category" -msgstr "Preskoči kategorijo" - -#: config/prefs.php.dist:31 config/prefs.php.dist:41 -msgid "Sort news by" -msgstr "Razvrsti novice po" - -#: add.php:154 templates/edit/info.php:29 lib/Forms/Search.php:48 -msgid "Sort order" -msgstr "Vrstni red" - -#: add.php:136 templates/edit/info.php:37 lib/Forms/Search.php:38 -msgid "Source" -msgstr "Vir" - -#: admin/sources/delete.php:30 -msgid "Source deleted." -msgstr "Vir je bil izbrisan." - -#: add.php:138 templates/edit/info.php:41 -msgid "Source link" -msgstr "Izvirna novica" - -#: templates/news/info.php:18 -msgid "Source media" -msgstr "Vir novice" - -#: templates/news/info.php:13 -msgid "Source news" -msgstr "Izvirna novica" - -#: admin/sources/edit.php:45 -msgid "Source saved succesfully." -msgstr "Vir je bil uspešno osvežen." - -#: admin/sources/delete.php:28 admin/sources/delete.php:33 -msgid "Source was not deleted." -msgstr "Vir ni bil izbrisan." - -#: admin/tabs.php:24 lib/Block/sources.php:3 lib/Block/sources.php:21 -msgid "Sources" -msgstr "Viri" - -#: admin/sources/index.php:17 -msgid "Sources Administration" -msgstr "Urejanje virov" - -#: add.php:222 -msgid "Sponsored" -msgstr "Komercialna" - -#: templates/edit/header.inc:6 lib/Forms/Search.php:31 -msgid "Status" -msgstr "Status" - -#: lib/News.php:1126 -msgid "Tag cloud" -msgstr "Tagi novic" - -#: add.php:145 lib/Block/tags_cloud.php:3 lib/Block/tags_cloud.php:24 -msgid "Tags" -msgstr "Tagi" - -#: templates/news/blog.php:7 -msgid "Talkbacks to this article:" -msgstr "Talkback na to novico:" - -#: templates/news/ulaform.php:13 -msgid "Thanks" -msgstr "Hvala" - -#: templates/block/news.php:18 templates/block/titles.php:20 -msgid "There are no news to display." -msgstr "Ni novic za prikaz." - -#: lib/News.php:557 -#, php-format -msgid "There requested news %s don't exist." -msgstr "Izbrana novica ne %s obstaja." - -#: news.php:29 -msgid "There requested version don't exist." -msgstr "Izbrana verzja ne obstaja." - -#: add.php:433 -msgid "There was an error creating gallery: " -msgstr "Prišlo je do napake pri tvorjenju galerije: " - -#: add.php:449 -#, fuzzy -msgid "There was an error with the uploaded image: " -msgstr "Pršlo je do napake pri nalaganju slike: " - -#: add.php:158 templates/news/threads.php:6 -#, php-format -msgid "Threads in %s" -msgstr "Debate v %s" - -#: add.php:143 templates/edit/header.inc:7 lib/Forms/Search.php:43 -#: lib/Block/my_comments.php:56 config/prefs.php.dist:30 -msgid "Title" -msgstr "Naslov" - -#: templates/news/tools.php:3 -msgid "Tools" -msgstr "Orodja" - -#: templates/news/blog.php:22 -msgid "Trackback this blog on this site." -msgstr "Vpišite blog na to novico." - -#: lib/News.php:703 -#, php-format -msgid "URL already trackbacked: %s" -msgstr "URL je bil že zapisan: %s" - -#: templates/edit/row.php:42 lib/Forms/Search.php:28 -msgid "Unconfirmed" -msgstr "Nepotrjena" - -#: templates/edit/row.php:27 -msgid "Unlock" -msgstr "Odkleni" - -#: lib/Forms/Search.php:52 -msgid "Unpublish" -msgstr "Odstrani ob" - -#: templates/edit/info.php:17 -msgid "Unpublish date" -msgstr "Odstrani dne" - -#: add.php:118 add.php:576 templates/edit/info.php:86 -msgid "Update" -msgstr "Ažuriraj" - -#: templates/sources/index.php:7 admin/sources/edit.php:33 -msgid "Url" -msgstr "Url" - -#: templates/news/blog.php:16 -msgid "Use the following link to trackback from your own site: " -msgstr "Uporabite sledeči naslov za trakback z vaše strani: " - -#: templates/reads/header.inc:6 templates/edit/header.inc:9 -#: lib/Forms/Search.php:53 lib/Block/my_comments.php:57 -msgid "User" -msgstr "Uporabnik" - -#: templates/edit/info.php:94 -msgid "View" -msgstr "Preglej" - -#: admin/sources/index.php:32 -msgid "View articles" -msgstr "Preglej novice" - -#: admin/sources/index.php:29 -msgid "View items" -msgstr "Preglej novice" - -#: templates/edit/info.php:21 -msgid "Yes" -msgstr "Da" - -#: admin/tabs.php:15 -msgid "You are not authorised for this action." -msgstr "Niste avtorizirani za ta ukaz." - -#: mail.php:42 -msgid "You have no email set." -msgstr "Nimate nastavljenega email naslova." - -#: edit.php:18 -msgid "You have not editor permission on any category." -msgstr "Nimate uredniških pravic do nobene kategorije." - -#: edit.php:60 -msgid "activated" -msgstr "aktivirana" - -#: edit.php:52 -msgid "deactivated" -msgstr "deaktivirana" - -#: delete.php:73 -msgid "deleted" -msgstr "izbrisana" - -#: edit.php:68 -msgid "locked" -msgstr "zaklenjena" - -#: delete.php:75 -msgid "not deleted" -msgstr "ni zbrisana" - -#: edit.php:109 -msgid "renewed" -msgstr "povrnjena" - -#: edit.php:76 -msgid "unlocked" -msgstr "odklenjena" diff --git a/news/mail.php b/news/mail.php deleted file mode 100644 index b6dac1c11..000000000 --- a/news/mail.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$id = Horde_Util::getFormData('id'); -$row = $news->get($id); -if ($row instanceof PEAR_Error) { - $notification->push($row); - Horde::url('browse.php')->redirect(); -} - -/* Error handler */ -function _error($msg) -{ - $GLOBALS['notification']->push($msg, 'horde.error'); - News::getUrlFor('news', $GLOBALS['id'])->redirect(); -} - -if (!$registry->isAuthenticated()) { - _error(_("Only authenticated users can send mails.")); -} - -$to = Horde_Util::getFormData('email'); -if (empty($to)) { - _error(_("No mail entered.")); - exit; -} - -$from = $prefs->getValue('from_addr'); -if (empty($from)) { - _error(_("You have no email set.")); - exit; -} - -$body = sprintf(_("%s would you like to invite you to read the news\n Title: %s\n\n Published: %s \nLink: %s"), - $GLOBALS['registry']->getAuth(), - $row['title'], - $row['publish'], - News::getUrlFor('news', $id, true, -1)); - -$mail = new Horde_Mime_Mail(array('subject' => $row['title'], 'body' => $body, 'to' => $to, 'from' => $from, 'charset' => $GLOBALS['registry']->getCharset())); -try { - $mail->send($injector->getInstance('Horde_Mail')); - $notification->push(sprintf(_("News succesfully send to %s"), $to), 'horde.success'); -} catch (Horde_Mime_Exception $e) { - $notification->push($e); -} - -News::getUrlFor('news', $id)->redirect(); diff --git a/news/news.php b/news/news.php deleted file mode 100644 index f239a1495..000000000 --- a/news/news.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$id = Horde_Util::getFormData('id'); -$row = $news->get($id); - -// check if the news exists -if ($row instanceof PEAR_Error) { - $notification->push($row); - Horde::url('index.php')->redirect(); -} - -// check if the news exists -if (($version = Horde_Util::getFormData('version')) !== null) { - $sql = 'SELECT created, user_uid, content FROM ' . $news->prefix . '_versions WHERE id = ? AND version = ?'; - $version_data = $news->db->getRow($sql, array($id, $version), DB_FETCHMODE_ASSOC); - if (empty($version_data)) { - $notification->push(_("There requested version don't exist."), 'horde.error'); - exit; - } else { - $version_data['content'] = unserialize($version_data['content']); - $row['content'] = $version_data['content'][NLS::select()]['content']; - $row['title'] = $version_data['content'][NLS::select()]['title'] . - ' (v.' . $version . _(" by ") . $version_data['user_uid'] . - ' @ ' . News::dateFormat($version_data['created']) . ')'; - } -} else { - $news->logView($id); -} - -$title = $row['title']; -$template_path = News::getTemplatePath($row['category1'], 'news'); -$browse_url = Horde::url('browse.php'); - -require_once NEWS_TEMPLATES . '/common-header.inc'; -require_once NEWS_TEMPLATES . '/menu.inc'; - -require $template_path . 'news.php'; - -require_once $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/note.php b/news/note.php deleted file mode 100644 index dce3e2c40..000000000 --- a/news/note.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$id = Horde_Util::getFormData('id'); -$row = $news->get($id); -if ($row instanceof PEAR_Error) { - $notification->push($row); - Horde::url('browse.php')->redirect(); -} - -$body = $row['title'] . "\n\n" - . _("On") . ': ' . News::dateFormat($row['publish']) . "\n" - . _("Link") . ': ' . News::getUrlFor('news', $id) . "\n\n" - . strip_tags($row['content']); - -/* Create a new vNote object using this message's contents. */ -$vCal = new Horde_iCalendar(); -$vNote = &Horde_iCalendar::newComponent('vnote', $vCal); -$vNote->setAttribute('BODY', $body); - -/* Attempt to add the new vNote item to the requested notepad. */ -try { - $registry->call('notes/import', array($vNote, 'text/x-vnote')); - $notification->push(_("News sucessfuly added to you notes."), 'horde.success'); - header('Location: ' . $registry->getInitialPage('mnemo')); -} catch (Horde_Exception $e) { - $notification->push($e); - News::getUrlFor('news', $id)->redirect(); -} diff --git a/news/pdf.php b/news/pdf.php deleted file mode 100644 index 21e7cfb8f..000000000 --- a/news/pdf.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @package News - */ - -$no_compress = true; -require_once dirname(__FILE__) . '/lib/base.php'; - -$id = Horde_Util::getFormData('id'); -$row = $news->get($id); - -// Check if the news exists -if ($row instanceof PEAR_Error) { - $notification->push($row); - Horde::url('browse.php')->redirect(); -} - -// Set up the PDF object. -$pdf = new Horde_Pdf_Writer(); - -$pdf->setInfo('title', $row['title']); -$pdf->setInfo('author', $row['user']); -$pdf->setInfo('CreationDate', 'D:' . date('Ymdhis')); - -$pdf->open(); -$pdf->addPage(); -$pdf->setAutoPageBreak(true); -$pdf->setFont('Arial', '', 12); - -if ($row['picture']) { - $file = $conf['vfs']['params']['vfsroot'] . '/' - . News::VFS_PATH . '/images/news/big/' - . $id . '.' . $conf['images']['image_type']; - try { - $pdf->image($file, 120, 20); - } catch (Horde_Pdf_Exception $e) { - Horde::logMessage($e, 'INFO'); - } -} - -$pdf->setFillColor('rgb', 200/255, 220/255, 255/255); -$pdf->cell(0, 6, $row['title'], 0, 1, 'L', 1); -$pdf->newLine(4); - -$pdf->write(12, _("On") . ': ' . News::dateFormat($row['publish']) . "\n"); -$pdf->write(12, _("Link") . ': ' . News::getUrlFor('news', $id, true) . "\n\n", News::getUrlFor('news', $id, true)); -$pdf->multiCell(0, 12, Horde_String::convertCharset(strip_tags($row['content']), $GLOBALS['registry']->getCharset(), 'UTF-8')); - -$browser->downloadHeaders($id . '.pdf', 'application/pdf'); -echo $pdf->getOutput(); diff --git a/news/po/messages.mo b/news/po/messages.mo deleted file mode 100644 index e54f6c97a5e75fa38b49c64d410388b7cbf84c22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9367 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 N#B>u5F65uY{4Y=ow&ef- diff --git a/news/print.php b/news/print.php deleted file mode 100644 index 49f1b6f39..000000000 --- a/news/print.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$id = Horde_Util::getFormData('id'); -$version = Horde_Util::getFormData('version', false); -$row = $news->get($id); -$template_path = News::getTemplatePath($row['category1'], 'news'); - -require_once NEWS_TEMPLATES . '/print/header.inc'; -require $template_path . 'news.inc'; -require_once NEWS_TEMPLATES . '/print/footer.inc'; diff --git a/news/reads.php b/news/reads.php deleted file mode 100644 index 1d89dec57..000000000 --- a/news/reads.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -if (!$registry->isAuthenticated()) { - $registry->authenticateFailure('news'); -} - -$id = Horde_Util::getFormData('id', 0); -$actionID = Horde_Util::getFormData('actionID', false); -$url = Horde::url('reads.php'); - -$sql = 'SELECT id, user, ip, readdate FROM ' . $news->prefix . '_user_reads WHERE '; -if ($actionID) { - $title = $actionID; - $result = $news->db->getAll($sql . 'user = ? ORDER BY readdate DESC', array($actionID), DB_FETCHMODE_ASSOC); -} else { - $result = $news->db->getAll($sql . 'id = ? ORDER BY readdate DESC', array($id), DB_FETCHMODE_ASSOC); - $title = sprintf(_("News %s"), $id); -} - -if ($result instanceof PEAR_Error) { - var_dump($result); - exit; -} - -Horde::addScriptFile('tables.js', 'horde'); -Horde::includeScriptFiles(); -Horde_Themes::includeStylesheetFiles(); - -// require_once NEWS_TEMPLATES . '/common-header.inc'; -require_once NEWS_TEMPLATES . '/reads/header.inc'; - -foreach ($result as $row) { - require NEWS_TEMPLATES . '/reads/row.inc'; -} - -// require_once $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/rss/comments.php b/news/rss/comments.php deleted file mode 100644 index ce1103873..000000000 --- a/news/rss/comments.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ - -$news_authentication = 'none'; -require_once dirname(__FILE__) . '/../lib/base.php'; - -$cache_key = 'news_rss_comments'; -$rss = $cache->get($cache_key, $conf['cache']['default_lifetime']); -if (!$rss) { - $list = News::getLastComments(50); - $title = _("Last comments"); - - $rss = 'getCharset() . '" ?> - - - ' . htmlspecialchars($title) . ' - ' . str_replace('_', '-', strtolower($registry->preferredLang())) . ' - ' . date('r') . ' - ' . htmlspecialchars($title) . ' - ' . Horde::url('index.php', true, -1) . ' - ' . htmlspecialchars($registry->get('name')) . ''; - - foreach ($list as $comment) { - $rss .= ' - - ' . htmlspecialchars($comment['message_subject']) . ' - ' . $comment['read_url'] . ' - ' . $comment['read_url'] . ' - ' . date('r', strtotime($comment['message_date'])) . ' - - '; - } - - $rss .= ' - -'; - - $cache->set($cache_key, $rss); -} - -header('Content-type: text/xml; charset=' . $GLOBALS['registry']->getCharset()); -echo $rss; diff --git a/news/rss/index.php b/news/rss/index.php deleted file mode 100644 index 3393c5daf..000000000 --- a/news/rss/index.php +++ /dev/null @@ -1,55 +0,0 @@ - - */ - -$news_authentication = 'none'; -require_once dirname(__FILE__) . '/../lib/base.php'; - -// Show a specific user? -$cache_key = 'news_rss_index'; - -$rss = $cache->get($cache_key, $conf['cache']['default_lifetime']); -if (!$rss) { - - $title = $registry->get('name', 'horde'); - - $read_url = Horde::url('read.php', true, -1); - $rss = 'getCharset() . '" ?> - - - ' . htmlspecialchars($title) . ' - ' . str_replace('_', '-', strtolower($registry->preferredLang())) . ' - ' . date('r') . ' - ' . htmlspecialchars($title) . ' - ' . Horde::url('index.php', true, -1) . ' - ' . htmlspecialchars($registry->get('name')) . ''; - - $rss .= ' - - ' . _("Last news") . ' - ' . Horde::url('rss/news.php', true, -1) . ' - '; - - $rss .= ' - - ' . _("Last comments") . ' - ' . Horde::url('rss/comments.php', true, -1) . ' - '; - - $rss .= ' - - '; - - $cache->set($cache_key, $rss); -} - -header('Content-type: text/xml'); -echo $rss; diff --git a/news/rss/news.php b/news/rss/news.php deleted file mode 100755 index 44577ca67..000000000 --- a/news/rss/news.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @author McLion - */ - -$news_authentication = 'none'; -require_once dirname(__FILE__) . '/../lib/base.php'; - -$cache_key = 'news_rss_news'; -$rss = $cache->get($cache_key, $conf['cache']['default_lifetime']); -if (empty($rss)) { - - /* query preparation */ - $query = 'SELECT n.id, publish, n.user, n.source, n.sourcelink, ' . - 'n.category1, n.category2, n.comments, n.picture, n.chars, nl.content, ' . - 'nl.title, nl.abbreviation ' . - 'FROM ' . $news->prefix . ' AS n, ' . $news->prefix . '_body AS nl ' . - 'WHERE n.status="' . News::CONFIRMED . '" AND n.publish<=NOW() ' . - 'AND nl.lang="' . $registry->preferredLang() . '" AND n.id=nl.id ORDER BY publish DESC'; - $rssbody = ''; - $query = $news->db->modifyLimitQuery($query, 0, 10); - $list = $news->db->getAssoc($query, true, array(), DB_FETCHMODE_ASSOC); - $categories = $news_cat->getCategories(false); - $title = sprintf(_("Last news"), $registry->get('name', 'horde')); - - $lastnewstime = 0; - foreach ($list as $news_id => $news) { - $news_link = News::getUrlFor('news', $news_id, true); - $rssbody .= ' - - - ' . htmlspecialchars($news['title']) . ' - ' . htmlspecialchars($news['user']). ' - ' . $news_link . ' - ' . $news_link . ' - ' . $news_link . '#comments - - ' . date('r', strtotime($news['publish'])) . ' - - '; - - if (strtotime($news['publish']) > $lastnewstime) { - $lastnewstime = strtotime($news['publish']); - } - } - - // Wee need the last published news time - $rssheader = 'getCharset() . '" ?> - - - ' . htmlspecialchars($title) . ' - ' . str_replace('_', '-', strtolower($registry->preferredLang())) . ' - ' . date('r', $lastnewstime) . ' - ' . htmlspecialchars($title) . ' - ' . Horde::url('index.php', true, -1) . ' - ' . htmlspecialchars($registry->get('name')) . ''; - - $rssfooter = ' - -'; - - // build rss - $rss = $rssheader . $rssbody . $rssfooter; - - $cache->set($cache_key, $rss); -} - -header('Content-type: text/xml; charset=utf-8'); -echo $rss; diff --git a/news/scripts/sql/news.mysql.sql b/news/scripts/sql/news.mysql.sql deleted file mode 100644 index 261cf70a1..000000000 --- a/news/scripts/sql/news.mysql.sql +++ /dev/null @@ -1,107 +0,0 @@ -CREATE TABLE news ( - id smallint(5) UNSIGNED NOT NULL auto_increment, - sortorder tinyint(2) NOT NULL DEFAULT '0', - status tinyint(1) UNSIGNED NOT NULL DEFAULT '0', - view_count smallint(5) UNSIGNED NOT NULL DEFAULT '0', - publish datetime DEFAULT NULL, - unpublish datetime DEFAULT NULL, - submitted datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - updated timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, - user varchar(11) NOT NULL DEFAULT '', - editor varchar(11) NOT NULL DEFAULT '', - sourcelink varchar(34) NOT NULL DEFAULT '', - source varchar(11) DEFAULT NULL, - category1 smallint(5) UNSIGNED NOT NULL DEFAULT '0', - category2 smallint(5) UNSIGNED NOT NULL DEFAULT '0', - comments smallint(5) NOT NULL DEFAULT '0', - chars smallint(5) UNSIGNED NOT NULL DEFAULT '0', - attachments tinyint(1) UNSIGNED NOT NULL DEFAULT '0', - picture int(4) NOT NULL DEFAULT '0', - gallery int(10) UNSIGNED NOT NULL DEFAULT '0', - selling varchar(50) DEFAULT NULL, - trackbacks int(10) UNSIGNED NOT NULL DEFAULT '0', - form_id smallint(5) UNSIGNED NOT NULL DEFAULT '0', - form_ttl int(10) UNSIGNED NOT NULL DEFAULT '0', - PRIMARY KEY (id), - KEY datum (publish), - KEY sortorder (sortorder), - KEY status (status), - KEY user (user), - KEY cat (category1) -); - -CREATE TABLE news_files ( - file_id int(10) UNSIGNED NOT NULL DEFAULT '0', - news_id int(10) UNSIGNED NOT NULL DEFAULT '0', - news_lang varchar(5) NOT NULL, - file_name varchar(85) NOT NULL DEFAULT '', - file_size int(10) UNSIGNED NOT NULL DEFAULT '0', - file_type varchar(85) NOT NULL DEFAULT '', - PRIMARY KEY (file_id), - KEY news (news_id, news_lang) -); - -CREATE TABLE news_body ( - id smallint(5) UNSIGNED NOT NULL DEFAULT '0', - lang varchar(5) NOT NULL DEFAULT '0', - title varchar(67) NOT NULL DEFAULT '', - abbreviation text NOT NULL, - content text NOT NULL, - picture_comment varchar(255); - tags varchar(255); - PRIMARY KEY (id,lang) -); - -CREATE TABLE news_categories ( - category_id int(10) UNSIGNED NOT NULL auto_increment, - category_name varchar(50) NOT NULL, - category_description varchar(255) DEFAULT NULL, - category_parentid int(10) UNSIGNED NOT NULL, - category_form varchar(50) NOT NULL, - category_image int(1) UNSIGNED NOT NULL, - PRIMARY KEY (category_id) -); - -CREATE TABLE news_categories_nls ( - category_id int(10) UNSIGNED NOT NULL, - category_nls char(5) NOT NULL, - category_name varchar(50) NOT NULL, - category_description varchar(255) NOT NULL, - PRIMARY KEY (category_id, category_nls), - KEY category_nls (category_nls) -); - -CREATE TABLE news_sources ( - source_id int(10) UNSIGNED NOT NULL, - source_name varchar(255) NOT NULL, - source_url varchar(255) NOT NULL, - PRIMARY KEY (source_id) -); - -CREATE TABLE news_trackback ( - id int(11) NOT NULL, - excerpt text, - created datetime NOT NULL, - title varchar(255) NOT NULL, - url varchar(255) NOT NULL, - blog_name varchar(255) NOT NULL, - KEY created (created), - KEY id (id) -); - -CREATE TABLE news_user_reads ( - id int(10) UNSIGNED NOT NULL DEFAULT '0', - user varchar(85) NOT NULL DEFAULT '', - ip varchar(9) NOT NULL DEFAULT '', - readdate datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - KEY id (id) -); - -CREATE TABLE news_versions ( - id int(10) UNSIGNED NOT NULL DEFAULT '0', - version float UNSIGNED NOT NULL DEFAULT '0', - created datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - user_uid varchar(85) NOT NULL DEFAULT '', - content text NOT NULL, - PRIMARY KEY (id,version) -); diff --git a/news/scripts/upgrades/20070302_trackback.sql b/news/scripts/upgrades/20070302_trackback.sql deleted file mode 100644 index 3769f3ea0..000000000 --- a/news/scripts/upgrades/20070302_trackback.sql +++ /dev/null @@ -1,13 +0,0 @@ -ALTER TABLE `news` CHANGE `reads` `view_count` SMALLINT( 5 ) UNSIGNED NOT NULL DEFAULT '0'; -ALTER TABLE `news` ADD `trackbacks` SMALLINT NOT NULL DEFAULT '0'; - -CREATE TABLE `news_trackback` ( - `id` int(11) NOT NULL, - `excerpt` text, - `created` datetime NOT NULL, - `title` varchar(255) NOT NULL, - `url` varchar(255) NOT NULL, - `blog_name` varchar(255) NOT NULL, - KEY `created` (`created`), - KEY `id` (`id`) -); diff --git a/news/scripts/upgrades/20070609_sponsored.sql b/news/scripts/upgrades/20070609_sponsored.sql deleted file mode 100644 index e86f428ca..000000000 --- a/news/scripts/upgrades/20070609_sponsored.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `news2` ADD `sponsored` TINYINT( 1 ) UNSIGNED NOT NULL AFTER `sourcelink` ; -ALTER TABLE `news2` ADD `parents` VARCHAR( 255 ) NOT NULL AFTER `sponsored` ; \ No newline at end of file diff --git a/news/scripts/upgrades/20071220_tags.sql b/news/scripts/upgrades/20071220_tags.sql deleted file mode 100644 index 5dc905e11..000000000 --- a/news/scripts/upgrades/20071220_tags.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `news_body` ADD `tags` VARCHAR( 255 ) AFTER `picture_comment` ; \ No newline at end of file diff --git a/news/search.php b/news/search.php deleted file mode 100644 index 01c6b6b3b..000000000 --- a/news/search.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @package News - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -// Default vars -$title = _("Browse"); -$page = Horde_Util::getGet('news_page', 0); -$per_page = $prefs->getValue('per_page'); -$browse_url = Horde::url('browse.php'); -$cid = Horde_Util::getGet('cid'); - -$vars = Horde_Variables::getDefaultVariables(); -$form = new News_Search($vars); -$form->getInfo(null, $criteria); - -// Count rows -$count = $news->countNews($criteria); -if ($count instanceof PEAR_Error) { - echo $count->getMessage() . ': ' . $count->getDebugInfo(); - exit; -} - -// Select rows -$rows = $news->listNews($criteria, $page*$per_page, $per_page, null); -if ($rows instanceof PEAR_Error) { - echo $rows->getMessage() . ': ' . $rows->getDebugInfo(); - exit; -} - -$pager = News_Search::getPager($criteria, $count, 'search.php'); - -$pager->preserve($criteria); - -// If we have only one row redirect ot it -if ($count == 1 && sizeof($cats) < 2 && $page < 1) { - News::getUrlFor('news', $rows[0]['id'])->redirect(); -} - - -require_once NEWS_TEMPLATES . '/common-header.inc'; -require_once NEWS_TEMPLATES . '/menu.inc'; - -$form->renderActive(null, null, null, 'post'); - -$browse_template_path = News::getTemplatePath($cid, 'browse'); -require_once $browse_template_path . 'header.inc'; -foreach ($rows as $row) { - require $browse_template_path . 'row.inc'; -} -require_once $browse_template_path . '/footer.inc'; - -require_once $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/news/tags.php b/news/tags.php deleted file mode 100644 index 55ddfe3dd..000000000 --- a/news/tags.php +++ /dev/null @@ -1,40 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you - * did not receive this file, see http://cvs.horde.org/co.php/news/LICENSE. - * - * $Id: browse.php 76 2007-12-19 13:57:35Z duck $ - * - * @author Duck - * @package News - */ -define('NEWS_BASE', dirname(__FILE__)); -require_once NEWS_BASE . '/lib/base.php'; - -$remove = array("!", "'", '"', "?", ".", ",", ";", ":", ')', '(', 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, '«', '»', '&', '+', '-', '*'); - -$result = $news->db->query('UPDATE news_body SET tags = ""'); -$result = $news->db->query('SELECT id, title FROM news_body WHERE tags = "" ORDER BY id ASC'); -while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) { - $row['title'] = Horde_String::lower($row['title'], true); - $row['title'] = str_replace($remove, '', $row['title']); - $tags = explode(' ', $row['title']); - foreach ($tags as $i => $tag) { - if (strlen($tag) < 4) { - unset($tags[$i]); - } - } - if (empty($tags)) { - continue; - } - $tags = implode(' ', $tags); - echo $tags . '
'; - $params = array($tags, $row['id']); - $news->db->query('UPDATE news_body SET tags = ? WHERE id = ?', $params); -} - -echo 'done'; diff --git a/news/templates/add/before.inc b/news/templates/add/before.inc deleted file mode 100755 index e69de29bb..000000000 diff --git a/news/templates/block/news.php b/news/templates/block/news.php deleted file mode 100644 index 1fab9dd9f..000000000 --- a/news/templates/block/news.php +++ /dev/null @@ -1,19 +0,0 @@ -news)): ?> - -news as $news_id => $news) { ?> -
- - - - - -

- \ No newline at end of file diff --git a/news/templates/block/titles.php b/news/templates/block/titles.php deleted file mode 100644 index 504b1d54a..000000000 --- a/news/templates/block/titles.php +++ /dev/null @@ -1,21 +0,0 @@ -news)): ?> - - - -news as $news_id => $news) { ?> - - - - - -
-getValue('date_format'), strtotime($news['publish'])) . ' - '; -echo Horde::link(News::getUrlFor('news', $news['id']), $news['abbreviation']); -echo $news['title'] . ''; -?> -
- - -

- diff --git a/news/templates/browse/footer.inc b/news/templates/browse/footer.inc deleted file mode 100755 index 10cc5e347..000000000 --- a/news/templates/browse/footer.inc +++ /dev/null @@ -1 +0,0 @@ -render(); ?> diff --git a/news/templates/browse/header.inc b/news/templates/browse/header.inc deleted file mode 100755 index 21ac9eedd..000000000 --- a/news/templates/browse/header.inc +++ /dev/null @@ -1,3 +0,0 @@ -
()
-render(); ?> - diff --git a/news/templates/browse/row.inc b/news/templates/browse/row.inc deleted file mode 100755 index 994cbc926..000000000 --- a/news/templates/browse/row.inc +++ /dev/null @@ -1,12 +0,0 @@ -

- - -'; ?> - - -
- ...
- - - - -

\ No newline at end of file diff --git a/news/templates/categories/delete.html b/news/templates/categories/delete.html deleted file mode 100755 index 7adede239..000000000 --- a/news/templates/categories/delete.html +++ /dev/null @@ -1,9 +0,0 @@ - - - -
-
Categories
- -
- - \ No newline at end of file diff --git a/news/templates/categories/edit.html b/news/templates/categories/edit.html deleted file mode 100755 index 7adede239..000000000 --- a/news/templates/categories/edit.html +++ /dev/null @@ -1,9 +0,0 @@ - - - -
-
Categories
- -
- - \ No newline at end of file diff --git a/news/templates/categories/index.html b/news/templates/categories/index.html deleted file mode 100755 index c314ca778..000000000 --- a/news/templates/categories/index.html +++ /dev/null @@ -1,5 +0,0 @@ - - - -
Categories
- diff --git a/news/templates/categories/index.php b/news/templates/categories/index.php deleted file mode 100644 index 9dcfe5714..000000000 --- a/news/templates/categories/index.php +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - -categories as $category_id => $category) { ?> - - - - - - - - - -
add_url ?>
-categories[$category['category_parentid']]['category_name'] . - ' - ' . $category['category_parentid']; -} -?>
\ No newline at end of file diff --git a/news/templates/common-header.inc b/news/templates/common-header.inc deleted file mode 100644 index e8b17bcf6..000000000 --- a/news/templates/common-header.inc +++ /dev/null @@ -1,31 +0,0 @@ -getCharset()); - header('Vary: Accept-Language'); -} -?> - - - - -' : '' ?> - -get('name'); -if (!empty($title)) { - $page_title .= ' :: ' . $title; -} - -Horde::outputMetaTags(); -Horde::includeScriptFiles(); - -?> -<?php echo htmlspecialchars($page_title) ?> - -" href="" type="application/rss+xml" /> -" href="" type="application/rss+xml" /> - - - - diff --git a/news/templates/edit/footer.inc b/news/templates/edit/footer.inc deleted file mode 100755 index 0582a5d8f..000000000 --- a/news/templates/edit/footer.inc +++ /dev/null @@ -1,4 +0,0 @@ - -render(); ?> - -
diff --git a/news/templates/edit/header.inc b/news/templates/edit/header.inc deleted file mode 100755 index 1e8daf490..000000000 --- a/news/templates/edit/header.inc +++ /dev/null @@ -1,17 +0,0 @@ -
- - - - - - - - - -' . _("Comments") . ''; -} -?> - - \ No newline at end of file diff --git a/news/templates/edit/info.php b/news/templates/edit/info.php deleted file mode 100644 index bf989d34f..000000000 --- a/news/templates/edit/info.php +++ /dev/null @@ -1,124 +0,0 @@ - - - diff --git a/news/templates/edit/row.php b/news/templates/edit/row.php deleted file mode 100644 index 2e0173fd9..000000000 --- a/news/templates/edit/row.php +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - -' . $row['comments'] . ''; -} -?> - diff --git a/news/templates/menu.inc b/news/templates/menu.inc deleted file mode 100644 index 3b6beca52..000000000 --- a/news/templates/menu.inc +++ /dev/null @@ -1,14 +0,0 @@ - - -notify(array('listeners' => 'status')) ?> diff --git a/news/templates/news/attachments.php b/news/templates/news/attachments.php deleted file mode 100644 index 5d04153a1..000000000 --- a/news/templates/news/attachments.php +++ /dev/null @@ -1,5 +0,0 @@ -
' . News::format_attached($id); -} diff --git a/news/templates/news/blog.php b/news/templates/news/blog.php deleted file mode 100644 index 89a8765ed..000000000 --- a/news/templates/news/blog.php +++ /dev/null @@ -1,39 +0,0 @@ -
-' . _("Blogs") . ''; - -// Blogs -if (!empty($row['trackback'])) { - echo _("Talkbacks to this article:") . '
    '; - foreach ($row['trackback'] as $trackback) { - echo '
  • ' . Horde::link($trackback['url'], $trackback['excerpt']) . $trackback['title'] . ' ' - . _("From: ") . $trackback['blog_name'] . ' @ ' . News::dateFormat($trackback['created']) . '
  • '; - } - echo '

'; -} - -$trackback_url = Horde_Util::addParameter(Horde::url('trackback.php', true), 'id', $id); -echo _("Use the following link to trackback from your own site: ") . - '

'; - -if ($registry->hasMethod('blogs/createUrl')) { - $intro = substr($plain_text, 0, 255) . '...'; - $blog_url = $registry->callByPackage('thomas', 'createUrl', array($trackback_url, $row['title'], $intro)); - echo Horde::link($blog_url) . '' . _("Trackback this blog on this site.") . '
'; -} - -$read_url = News::getUrlFor('news', $id); -?> - - diff --git a/news/templates/news/comments.php b/news/templates/news/comments.php deleted file mode 100644 index a200954fa..000000000 --- a/news/templates/news/comments.php +++ /dev/null @@ -1,21 +0,0 @@ -
--1 && - $registry->hasMethod('forums/doComments')) { - - $params = array('news', $id, 'commentCallback', true, null, null, - array('message_subject' => $row['title']), $conf['comments']['comment_template']); - - $comments = $registry->call('forums/doComments', $params); - - if (!empty($comments['threads'])) { - echo $comments['threads']; - } - - if (!empty($comments['comments'])) { - echo $comments['comments']; - } -} - diff --git a/news/templates/news/gallery.php b/news/templates/news/gallery.php deleted file mode 100644 index 5f9e37085..000000000 --- a/news/templates/news/gallery.php +++ /dev/null @@ -1,19 +0,0 @@ -get('webroot', 'horde') . '/vfs/.horde/ansel/'; - -echo '
'; -foreach ($images as $image_id => $image) { - $img_url = substr($image_id, -2) . '/%s/' . $image_id . '.jpg'; - echo "\n" . '
' . - Horde::link('#', $image['name'], '', '', Horde::popupJs($path . sprintf($img_url, 'screen'), array('width' => $conf['images']['image_width'], 'height' => $conf['images']['image_height'], 'urlencode' => true)). 'return false') . "\n" . - '' . - $image['caption']. '
'; -} -echo '
'; - diff --git a/news/templates/news/info.php b/news/templates/news/info.php deleted file mode 100644 index ef3ae6465..000000000 --- a/news/templates/news/info.php +++ /dev/null @@ -1,20 +0,0 @@ -' . _("News data") . ''; -echo _("By") . ': ' . Horde::link(Horde_Util::addParameter($browse_url, 'user', $row['user'])) . $row['user'] . '
'; -echo _("On") . ': ' . Horde::link(Horde_Util::addParameter($browse_url, 'publish', $row['publish'])) . News::dateFormat($row['publish']) . '
'; -echo _("Category") . ': ' . Horde::link(Horde_Util::addParameter($browse_url, 'cid', $row['category1'])) . $GLOBALS['news_cat']->getName($row['category1']) . '
'; - -$plain = preg_replace('/\s\s+/', ' ', trim(strip_tags($row['content']))); -echo _("Chars") . ': ' . number_format(strlen($plain)) . '
'; -echo _("Besed") . ': ' . number_format(substr_count($plain, ' ')) . '
'; - -if ($row['sourcelink']) { - echo _("Source news") . ': ' . Horde::externalUrl($row['sourcelink'], true) . _("Source news") . '
'; -} - -if ($row['source']) { - $sources = $news->getSources(true); - echo _("Source media") . ': ' . Horde::externalUrl($sources[$row['source']]['source_url'], true) . - $sources[$row['source']]['source_name'] . '
'; -} diff --git a/news/templates/news/mail.php b/news/templates/news/mail.php deleted file mode 100644 index d817b1f56..000000000 --- a/news/templates/news/mail.php +++ /dev/null @@ -1,7 +0,0 @@ -
-
- - - - - diff --git a/news/templates/news/news.php b/news/templates/news/news.php deleted file mode 100644 index c51f1ae69..000000000 --- a/news/templates/news/news.php +++ /dev/null @@ -1,46 +0,0 @@ -
-

-
- - - - - - - -
- -"> - -
-');"> - -
-\n"; -} else { - echo _("Primary category") . ': ' . $row['category1'] . '!!!
' . "\n"; -} - -if ($row['category2']>0) { - echo _("Secondary category") . ': ' . $allowed_cats[$row['category2']] . "
\n"; -} - -if (substr($row['unpublish'], 0, 1) != 0) { - echo _("Unpublish date") . ': ' . $row['unpublish'] . "
\n"; -} - -if ($conf['comments']['allow']) { - echo _("Allow comments") . ': ' . ($row['comments']>-1 ? _("Yes") : _("No")) . "
\n"; -} - -if ($row['editor']) { - echo _("Editor") . ': ' . $row['editor'] . "
\n"; -} - -if ($row['sortorder']) { - echo _("Sort order") . ': ' . $row['sortorder'] . "
\n"; -} - -if (isset($row['parents'])) { - echo _("Parents") . ': ' . sizeof($row['parents']) . "
\n"; -} - -if (!empty($row['source']) && isset($GLOBALS['cfgSources'][$row['source']])) { - echo _("Source") . ': ' . $GLOBALS['cfgSources'][$row['source']]['title'] . '
'; -} - -if (isset($row['sourcelink'])) { - echo _("Source link") . ': ' . $row['sourcelink'] . '
'; -} - -// schedul -if (!empty($row['selling'])) { - $item = explode('|', $row['selling']); - echo _("Selling item") . ': ' . $registry->get('name', $registry->hasInterface($item[0])); - $articles = $registry->call($item[0] . '/listCostObjects'); - foreach ($articles[0]['objects'] as $item_data) { - if ($item_data['id'] == $item[1]) { - echo ' - ' . $item_data['name']; - break; - } - } -} - -// Form -if (!empty($row['form'])) { - // -} - -if ($row['attachments']) { - echo News::format_attached($id); -} - -?> -
-getVerisons($id); -if ($versions instanceof PEAR_Error) { - echo $versions->getMessage(); - echo $versions->getDebugInfo(); -} - -unset($versions[0]); // current version - -if (sizeof($versions)>0) { - echo _("Edit history: ") . '
'; - - foreach ($versions as $version) { - - switch ($version['action']) { - case 'update': - echo _("Update"); - break; - default: - echo _("Insert"); - break; - } - echo _(" by ") . $version['user_uid'] . _(" at ") . $version['created'] . "\n("; - - $url = Horde_Util::addParameter(Horde::url('news.php'), array('id' => $id, 'version' => $version['version'])); - echo Horde::link($url, _("View"), '', '_blank', '', _("View")) . _("View") . ' | '; - - $url = Horde_Util::addParameter(Horde::url('edit.php'), array('id' => $id, 'actionID' => 'renew')); - echo Horde::link(Horde_Util::addParameter($url,'version', $version['version']),_("Renew")) . _("Renew") . ' | '; - - $url = Horde_Util::addParameter(Horde::url('diff.php'), array('id' => $id, 'version' => $version['version'])); - echo Horde::link('#', _("Diff"), '', '', Horde::popupJs($url, array('urlencode' => true)) . 'return false;') . _("Diff") . ' '; - - echo ')
' . "\n"; - } -} - -?> -
- -
- $page, 'id' => $row['id'])); -echo Horde::link($url,_("Edit")) . - Horde::img('edit.png', _("Edit"), '', $img_dir) . '  '; - -echo Horde::link(Horde_Util::addParameter($browse_url, 'id', $row['id']), _("Info")) . - Horde::img('devel.png', _("Info"), '', $img_dir). '  '; - -/* admins options */ -if ($registry->isAdmin() || isset($allowed_cats[$row['category1']]) || isset($allowed_cats[$row['category2']])) { - - if ($row['status'] == News::CONFIRMED) { - $url = Horde_Util::addParameter($browse_url, array('page' => $page, 'actionID' => 'deactivate', 'id' => $row['id'])); - echo Horde::link($url,_("Deactivate")) . Horde::img('cross.png', _("Deactivate"), '', $img_dir) . ' '; - } else { - $url = Horde_Util::addParameter($browse_url, array('page' => $page, 'actionID' => 'activate', 'id' => $row['id'])); - echo Horde::link($url,_("Activate")) . Horde::img('tick.png', _("Activate"), '', $img_dir) . ' '; - - $url = Horde_Util::addParameter(Horde::url('delete.php'), 'id', $row['id']); - echo Horde::link($url,_("Delete"), '', '', '', _("Delete")) . Horde::img('delete.png', _("Delete"), '', $img_dir) . '  '; - - if ($row['status'] == News::LOCKED) { - $url = Horde_Util::addParameter($browse_url, array('page' => $page, 'actionID' => 'unlock', 'id' => $row['id'])); - echo Horde::link($url,_("Unlock")) . Horde::img('map.png', '', '', $img_dir) . ' '; - } else { - $url = Horde_Util::addParameter($browse_url, array('page' => $page, 'actionID' => 'lock', 'id' => $row['id'])); - echo Horde::link($url,_("Lock")) . Horde::img('locked.png', '', '', $img_dir) . ' '; - } - } -} - -?> - - - true)) . 'return false', $row['view_count']) . number_format($row['view_count']) . ''; -?> -
- - - - -
-' - . '' - . '
' - . $row['picture_comment'] - . ''; -} - -$plain_text = trim(strip_tags($row['content'])); -echo '
' . substr($plain_text, 0, 1) . '
'; -echo $row['content']; - -if ($row['sponsored']) { - echo '' . _("* Sponsored news") . ''; -} - -require NEWS_TEMPLATES . '/news/parents.php'; -require NEWS_TEMPLATES . '/news/attachments.php'; -require NEWS_TEMPLATES . '/news/ulaform.php'; -require NEWS_TEMPLATES . '/news/selling.php'; -require NEWS_TEMPLATES . '/news/gallery.php'; -require NEWS_TEMPLATES . '/news/threads.php'; -require NEWS_TEMPLATES . '/news/comments.php'; - -?> -
- -
\ No newline at end of file diff --git a/news/templates/news/parents.php b/news/templates/news/parents.php deleted file mode 100644 index d4de7c162..000000000 --- a/news/templates/news/parents.php +++ /dev/null @@ -1,12 +0,0 @@ -
-'; - foreach ($row['parents'] as $parent_id => $data) { - echo '
  • ' . News::dateFormat($data['publish']) . ' ' - . Horde::link(News::getUrlFor('news', $parent_id), _("Read")) - . $data['title'] . ' (' . ($data['comments']> -1 ? $data['comments'] : 0) . ')'; - } - echo ''; -} diff --git a/news/templates/news/selling.php b/news/templates/news/selling.php deleted file mode 100644 index 806ab1e5c..000000000 --- a/news/templates/news/selling.php +++ /dev/null @@ -1,13 +0,0 @@ -
    -
    -call($item[0] . '/getSellingForm', $item[1]); - } catch (Horde_Exception $e) { - echo $e->getMessage(); - } -} - diff --git a/news/templates/news/threads.php b/news/templates/news/threads.php deleted file mode 100644 index 7eeb6e8f4..000000000 --- a/news/templates/news/threads.php +++ /dev/null @@ -1,14 +0,0 @@ -
    -' . sprintf(_("Threads in %s"), $registry->get('name', 'agora')) . ':'; - $agore_link = $registry->get('webroot', 'agora'); - echo ''; -} diff --git a/news/templates/news/today.php b/news/templates/news/today.php deleted file mode 100644 index 52d335f8b..000000000 --- a/news/templates/news/today.php +++ /dev/null @@ -1,13 +0,0 @@ -
    ' . _("On this day") . '
    '; -$img = Horde::img('news.png'); -echo $img . ' ' . Horde::link(Horde_Util::addParameter($browse_url, 'date', $row['publish'])) . _("News of this day.") . '
    '; - -if ($registry->hasInterface('schedul')) { - $img = Horde::img('schedul.png'); - $url = $registry->get('webroot', 'schedul') . '/browse.php'; - $url = Horde_Util::addParameter($url, array('actionID' => 'date', 'date' => $row['publish'])); - echo $img . ' ' . Horde::link($url) . _("Events on this day.") . '
    '; -} - diff --git a/news/templates/news/tools.php b/news/templates/news/tools.php deleted file mode 100644 index 7a74241d9..000000000 --- a/news/templates/news/tools.php +++ /dev/null @@ -1,25 +0,0 @@ -
    ' . _("Tools") . '
    '; - -$img = Horde::img('print.png'); -echo $img . ' ' . Horde::link('javascript:window.print()') . _("Printer firendly") . '
    '; - -$img = Horde::img('mime/pdf.png'); -echo $img . ' ' . Horde::link(Horde_Util::addParameter(Horde::url('pdf.php'), 'id', $id)) . _("PDF") . '
    '; - -/* Bookmark link */ -if ($registry->hasMethod('bookmarks/getAddUrl')) { - $api_params = array( - 'url' => News::getUrlFor('news', $id, true), - 'title' => $row['title']); - $url = $registry->call('bookmarks/getAddUrl', array($api_params)); - $img = Horde::img(Horde_Themes::img('trean.png', 'trean')); - echo $img . ' ' . Horde::link($url) . _("Add to bookmarks.") . '
    '; -} - -if ($registry->hasInterface('notes')) { - $img = Horde::img(Horde_Themes::img('mnemo.png', 'mnemo')); - $url = Horde_Util::addParameter(Horde::url('note.php', true), 'id', $id); - echo $img . ' ' . Horde::link($url) . _("Add to notes.") . '
    '; -} diff --git a/news/templates/news/ulaform.php b/news/templates/news/ulaform.php deleted file mode 100644 index f8e836956..000000000 --- a/news/templates/news/ulaform.php +++ /dev/null @@ -1,17 +0,0 @@ - $_SERVER['REQUEST_TIME'])) { - return; -} - -$form = $registry->callByPackage('ulaform', 'display', array($row['form_id'])); -if ($form instanceof PEAR_Error) { - echo $form; -} elseif ($form === true) { - echo _("Thanks"); -} else { - echo '

    ' . $form['title'] . '

    '; - echo $form['form']; -} diff --git a/news/templates/print/footer.inc b/news/templates/print/footer.inc deleted file mode 100755 index e69de29bb..000000000 diff --git a/news/templates/print/header.inc b/news/templates/print/header.inc deleted file mode 100755 index e69de29bb..000000000 diff --git a/news/templates/reads/footer.inc b/news/templates/reads/footer.inc deleted file mode 100755 index 000ca4b01..000000000 --- a/news/templates/reads/footer.inc +++ /dev/null @@ -1 +0,0 @@ - diff --git a/news/templates/reads/header.inc b/news/templates/reads/header.inc deleted file mode 100755 index c192b7959..000000000 --- a/news/templates/reads/header.inc +++ /dev/null @@ -1,10 +0,0 @@ -
    - - - - - - - - - diff --git a/news/templates/reads/row.inc b/news/templates/reads/row.inc deleted file mode 100755 index 56d758815..000000000 --- a/news/templates/reads/row.inc +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/news/templates/sources/index.php b/news/templates/sources/index.php deleted file mode 100644 index 87180309f..000000000 --- a/news/templates/sources/index.php +++ /dev/null @@ -1,18 +0,0 @@ -
    '; ?>'; ?>
    - - - - - - - - -sources as $source_id => $source) { ?> - - - - - - - -
    add_url ?>
    diff --git a/news/themes/graphics/folder_open.png b/news/themes/graphics/folder_open.png deleted file mode 100644 index 312f8be411a1f20cdb905bc611f4f4458c9d348e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 529 zcmV+s0`C2ZP)k%h|J>Z%zTW@4-T&Cw*wN9^(9qDW)&Ho{ z|D(|Vpw9oE&HtRt|C!4Fm&yOI#pja6|B%H0j>G?p!vBfD|G2oghrj=}wzh=6|9-mv zdAR>~w*Pgt|8unes;a7&tj=t(|7x%QXs-W~r^#lm|6{BFVXFUKsQ+1||5v2{Ripn= zp#M*w|CE%JOP&8moBu_b|9p|MJd^)AlK+H+gn)p6eSLi@i2ogb|8Q_{7kd8@cK;A{ z|4e1&WMpJRU*%n0T{c+dGgjpQU-l|d2HOaMl;3q9ooH|2&Rc?SRh z00DGTPE!Ct=GbNc006y7L_t&-83n;HO2c3n0MM5|UrZBqu;Ad*K^N)dTyG#a^_)F~ z7bt?z#UVJg1s%i;O`?hK1pq+YtYFvlBM_?%tmoTq1fhn_`iWiBk3xcr4c7B*H-@t` zy00Ot9*^&#;<|nrfaf+;T)D{P>EVqiH5_Zz!qbqhERABQQL(;@)c&pwNO|CIoSVVeE{DsDY* TL1z%Y00000NkvXXu0mjf7MvW% diff --git a/news/themes/graphics/mkdir.png b/news/themes/graphics/mkdir.png deleted file mode 100644 index 121f156933796a8535b584aff6fd307bb0d684a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 968 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR`Op|Nj5^l<&`{{C_{? z`}-;Xzfbx8eag9W$y25;rexI}U zy;Jfv!=Q7TUgsn%j|FAl^Gd$v6m?D0>6oU|IYrB391=?p95?{9ZWN4$z@QC*%g)Xr zK*uSR1o;L3#}61{Vx->!)rNbzIEGZ*ialp3)ZoD3axpC1OM>s`|NH&@`u+U;{QUp<|M~m-`T6!d z^YHNT?eO>R@9^;M^Xu*O?e6dG?eFaD?(6I9>gw$1>hbC6>+a|B?&tXE>G0?1@8{_0 z=jZ9==kMa=?Be9>fqw(-{I%q;pyJr=H1@r+}-5w*7@z$_uJj(+uY;Y z+~exi_2|^|+}Y^Y+2GgN;^))xCZ-rK6*xq@<&so}QeXoSU1Q znVFfGn3$KBmynQS_)I_HWha;oXY0uB(LzNA zW=9xXsHl - * @package News - */ - -$news_authentication = 'none'; -require_once dirname(__FILE__) . '/lib/base.php'; - -if ($browser->isRobot()) { - exit; -} - -header('Content-type: text/xml'); - -/* Try to create object */ -$trackback_data = array( - 'id' => Horde_Util::getFormData('id'), - 'host' => $_SERVER['REMOTE_ADDR'], - 'title' => Horde_Util::getFormData('title'), - 'excerpt' => Horde_Util::getFormData('excerpt'), - 'url' => Horde_Util::getFormData('url'), - 'blog_name' => Horde_Util::getFormData('blog_name') -); - -$trackback = News::loadTrackback($trackback_data); -if ($trackback instanceof PEAR_Error) { - echo Services_Trackback::getResponseError($trackback->getMessage(), 1); - exit; -} - -/* Check if the needed data is posted */ -foreach ($trackback_data as $key => $value) { - if ($key != 'excerpt' && empty($value)) { - echo Services_Trackback::getResponseError($key . ' is required', 2); - exit; - } -} - -/* Get the response and check if the request has all data */ -$request = $trackback->receive(); -if ($trackback instanceof PEAR_Error) { - echo Services_Trackback::getResponseError($request->getMessage(), 3); - exit; -} - -/* Check if the message is a spam */ -if (!empty($conf['trackback']['spamcheck'])) { - foreach ($conf['trackback']['spamcheck'] as $type) { - $trackback->createSpamCheck($type); - } - if ($trackback->checkSpam()) { - echo Services_Trackback::getResponseError('SPAM', 4); - exit; - } -} - -/* Check if the forum exists */ -$id = (int)$trackback->get('id'); -if ($id == 0) { - echo Services_Trackback::getResponseError(sprintf(_("Blog entry %s does not exist."), $id), 5); -} - -$news_data = $news->get($id); -if ($news_data instanceof PEAR_Error) { - echo Services_Trackback::getResponseError($news_data->getMessage(), 5); - exit; -} - -/* Store the trackback data */ -$result = $news->saveTrackback($id, - $trackback->get('title'), - $trackback->get('url'), - $trackback->get('excerpt'), - $trackback->get('blog_name'), - $trackback->get('trackback_url')); -if ($result instanceof PEAR_Error) { - echo Services_Trackback::getResponseError($result->getMessage(), 6); - exit; -} - -/* All done */ -echo Services_Trackback::getResponseSuccess(); diff --git a/skoli/LICENSE b/skoli/LICENSE deleted file mode 100644 index da074b87a..000000000 --- a/skoli/LICENSE +++ /dev/null @@ -1,48 +0,0 @@ -Version 1.0 - -Copyright (c) 2002-2005 The Horde Project. 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 acknowledgment: - - "This product includes software developed by the Horde Project - (http://www.horde.org/)." - -Alternately, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names "Horde", "The Horde Project", and "Mnemo" must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -core@horde.org. - -5. Products derived from this software may not be called "Horde" or -"Mnemo", nor may "Horde" or "Mnemo" appear in their name, without -prior written permission of the Horde Project. - -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 HORDE PROJECT 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 Horde Project. For more information on -the Horde Project, please see . diff --git a/skoli/README b/skoli/README deleted file mode 100644 index 098999b7d..000000000 --- a/skoli/README +++ /dev/null @@ -1,87 +0,0 @@ -What is Skoli? -============== - -:Contact: horde@lists.horde.org - -.. contents:: Contents -.. section-numbering:: - -Skoli is a simple administrative module for teachers. Several contacts -(students) will be summarized to a class. To each student one can then -enter marks, objectives, outcomes and absences. Besides offering a search -function Skoli also offers an export option in the CSV and TSV formats. - -This software is OSI Certified Open Source Software. OSI Certified is a -certification mark of the `Open Source Initiative`_. - -.. _`Open Source Initiative`: http://www.opensource.org/ - - -Obtaining Skoli ---------------- - -Further information on Skoli and the latest version can be obtained at - - http://www.horde.org/skoli/ - - -Documentation -------------- - -The following documentation is available in the Skoli distribution: - -:README_: This file -:LICENSE_: Copyright and license information -:`docs/CHANGES`_: Changes by release -:`docs/CREDITS`_: Project developers -:`docs/INSTALL`_: Installation instructions and notes -:`docs/TODO`_: Development TODO list -:`docs/UPGRADING`_: Pointers on upgrading from previous Skoli versions - - -Installation ------------- - -Instructions for installing Skoli can be found in the file INSTALL_ in the -``docs/`` directory of the Skoli distribution. - - -Assistance ----------- - -If you encounter problems with Skoli, help is available! - -The Horde Frequently Asked Questions List (FAQ), available on the Web at - - http://www.horde.org/faq/ - -The Horde Project runs a number of mailing lists, for individual applications -and for issues relating to the project as a whole. Information, archives, and -subscription information can be found at - - http://www.horde.org/mail/ - -Lastly, Horde developers, contributors and users also make occasional -appearances on IRC, on the channel #horde on the freenode Network -(irc.freenode.net). - - -Licensing ---------- - -For licensing and copyright information, please see the file LICENSE_ -in the Skoli distribution. - -Thanks, - -The Skoli team - - -.. _README: ?f=README.html -.. _LICENSE: http://www.horde.org/licenses/asl.php -.. _docs/CHANGES: ?f=CHANGES.html -.. _docs/CREDITS: ?f=CREDITS.html -.. _INSTALL: -.. _docs/INSTALL: ?f=INSTALL.html -.. _docs/TODO: ?f=TODO.html -.. _docs/UPGRADING: ?f=UPGRADING.html diff --git a/skoli/add.php b/skoli/add.php deleted file mode 100644 index 7dbc748a7..000000000 --- a/skoli/add.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ - -@define('SKOLI_BASE', dirname(__FILE__)); -require_once SKOLI_BASE . '/lib/base.php'; -require_once SKOLI_BASE . '/lib/Forms/Entry.php'; - -/* Redirect to create a new class if we don't have access to any class */ -if (count(Skoli::listClasses(false, Horde_Perms::EDIT)) == 0 && $GLOBALS['registry']->getAuth()) { - $notification->push(_("Please create a new Class first."), 'horde.message'); - Horde::url('classes/create.php', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$form = new Skoli_EntryForm($vars); - -// Execute if the form is valid. -if ($form->validate($vars)) { - $result = $form->execute(); - if (is_a($result, 'PEAR_Error')) { - $notification->push($result, 'horde.error'); - } else { - $notification->push(sprintf(_("The new entry for \"%s\" has been added."), $result), 'horde.success'); - } - - Horde::url('add.php', true) - ->add('class', $vars->get('class_id')) - ->redirect(); - exit; -} - -$title = $form->getTitle(); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -echo $form->renderActive($form->getRenderer(), $vars, 'add.php', 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/classes/create.php b/skoli/classes/create.php deleted file mode 100644 index 34c8c8ae6..000000000 --- a/skoli/classes/create.php +++ /dev/null @@ -1,46 +0,0 @@ -getAuth()) { - Horde::url('list.php', true)->redirect(); -} - -// Exit if we don't have access to addressbooks. -require_once SKOLI_BASE . '/lib/School.php'; -if (!count(Skoli_School::listAddressBooks())) { - $notification->push(_("You don't have access to any valid addressbook."), 'horde.error'); - Horde::url('classes/', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$form = new Skoli_CreateClassForm($vars); - -// Execute if the form is valid. -if ($form->validate($vars)) { - $result = $form->execute(); - if (is_a($result, 'PEAR_Error')) { - $notification->push($result, 'horde.error'); - } else { - $notification->push(sprintf(_("The class \"%s\" has been created."), $vars->get('name')), 'horde.success'); - $GLOBALS['display_classes'][] = $form->shareid; - $prefs->setValue('display_classes', serialize($GLOBALS['display_classes'])); - } - - Horde::url('classes/', true)->redirect(); -} - -$title = $form->getTitle(); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -echo $form->renderActive($form->getRenderer(), $vars, 'create.php', 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/classes/delete.php b/skoli/classes/delete.php deleted file mode 100644 index 7ae1d426b..000000000 --- a/skoli/classes/delete.php +++ /dev/null @@ -1,48 +0,0 @@ -getAuth()) { - Horde::url('list.php', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$class_id = $vars->get('c'); - -$class = $skoli_shares->getShare($class_id); -if (is_a($class, 'PEAR_Error')) { - $notification->push($class, 'horde.error'); - Horde::url('classes/', true)->redirect(); -} elseif (!$class->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)) { - $notification->push(_("You are not allowed to delete this class."), 'horde.error'); - Horde::url('classes/', true)->redirect(); -} - -$form = new Skoli_DeleteClassForm($vars, $class); - -// Execute if the form is valid (must pass with POST variables only). -if ($form->validate(new Horde_Variables($_POST))) { - $result = $form->execute(); - if (is_a($result, 'PEAR_Error')) { - $notification->push($result, 'horde.error'); - } elseif ($result) { - $notification->push(sprintf(_("The class \"%s\" has been deleted."), $class->get('name')), 'horde.success'); - } - - Horde::url('classes/', true)->redirect(); -} - -$title = $form->getTitle(); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -echo $form->renderActive($form->getRenderer(), $vars, 'delete.php', 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/classes/edit.php b/skoli/classes/edit.php deleted file mode 100644 index b4d0c999f..000000000 --- a/skoli/classes/edit.php +++ /dev/null @@ -1,75 +0,0 @@ -getAuth()) { - Horde::url('list.php', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$class = $skoli_shares->getShare($vars->get('c')); -if (is_a($class, 'PEAR_Error')) { - $notification->push($class, 'horde.error'); - Horde::url('classes/', true)->redirect(); -} elseif (!$class->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) { - $notification->push(_("You are not allowed to change this class."), 'horde.error'); - Horde::url('classes/', true)->redirect(); -} -$vars->set('school', $class->get('school')); -if (!$vars->exists('marks')) { - $vars->set('marks', $class->get('marks')); -} -if (!$vars->exists('address_book')) { - $vars->set('address_book', $class->get('address_book')); -} - -$form = new Skoli_EditClassForm($vars, $class); - -// Execute if the form is valid. -if ($form->validate($vars)) { - $original_name = $class->get('name'); - $result = $form->execute(); - if (is_a($result, 'PEAR_Error')) { - $notification->push($result, 'horde.error'); - } else { - if ($class->get('name') != $original_name) { - $notification->push(sprintf(_("The class \"%s\" has been renamed to \"%s\"."), $original_name, $class->get('name')), 'horde.success'); - } else { - $notification->push(sprintf(_("The class \"%s\" has been saved."), $original_name), 'horde.success'); - } - } - - Horde::url('classes/', true)->redirect(); -} - -if (!$vars->exists('name')) { - $vars->set('name', $class->get('name')); - $vars->set('description', $class->get('desc')); - $vars->set('category', $class->get('category')); - foreach ($form->_schoolproperties as $name) { - if ($name != 'marks') { - $vars->set($name, $class->get($name)); - } - } - $studentslist = current(Skoli::listStudents($vars->get('c'))); - $studentsvars = array(); - foreach ($studentslist['_students'] as $student) { - $studentsvars[] = $student['__key']; - } - $vars->set('students', $studentsvars); -} - -$title = $form->getTitle(); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -echo $form->renderActive($form->getRenderer(), $vars, 'edit.php', 'post'); -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/classes/index.php b/skoli/classes/index.php deleted file mode 100644 index 09be282f4..000000000 --- a/skoli/classes/index.php +++ /dev/null @@ -1,37 +0,0 @@ -getAuth()) { - Horde::url('list.php', true)->redirect(); -} - -$edit_url_base = Horde::url('classes/edit.php'); -$perms_url_base = Horde::url($registry->get('webroot', 'horde') . '/services/shares/edit.php?app=skoli', true); -$delete_url_base = Horde::url('classes/delete.php'); - -$classes = Skoli::listClasses(true); -$sorted_classes = array(); -foreach ($classes as $class) { - $sorted_classes[$class->getName()] = $class->get('name'); -} -asort($sorted_classes); - -$edit_img = Horde::img('edit.png', _("Edit")); -$perms_img = Horde::img('perms.png', _("Change Permissions")); -$delete_img = Horde::img('delete.png', _("Delete")); - -Horde::addScriptFile('tables.js', 'horde'); -$title = _("Manage Classes"); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -require SKOLI_TEMPLATES . '/classes/list.php'; -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/config/conf.xml b/skoli/config/conf.xml deleted file mode 100644 index 27caf8257..000000000 --- a/skoli/config/conf.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - Storage System Settings - - sql - - - - - - - - - - - - Settings for new Objects - - true - true - true - true - - - - - Address settings - - ask - - - - localsql - - - name - user - - - - - - %c - %g - %s - - - - - - - Menu settings - - true - - - - - - - diff --git a/skoli/config/prefs.php.dist b/skoli/config/prefs.php.dist deleted file mode 100644 index bf88f6376..000000000 --- a/skoli/config/prefs.php.dist +++ /dev/null @@ -1,205 +0,0 @@ - _("General Preferences"), - 'label' => _("Display Preferences"), - 'desc' => _("Change your sorting and display preferences."), - 'members' => array('initial_page', 'class_columns', 'sortby_class', 'sortdir_class', 'student_columns', 'sortby_student', 'sortdir_student', 'entry_details_wrap'), -); - -$prefGroups['contactlists'] = array( - 'column' => _("General Preferences"), - 'label' => _("Contact Lists"), - 'desc' => _("Change your settings for automatically create contact lists."), - 'members' => $GLOBALS['conf']['addresses']['contact_list'] == 'user' ? array('contact_list', 'contact_list_name') : array(), -); - -$prefGroups['marks'] = array( - 'column' => _("General Preferences"), - 'label' => _("Marks"), - 'desc' => _("Define a format for marks"), - 'members' => array('marks_roundby') -); - -// default view -$_prefs['initial_page'] = array( - 'value' => 'list', - 'locked' => false, - 'shared' => false, - 'type' => 'enum', - 'enum' => array('list' => _("List Classes"), - 'add' => _("New Entry"), - 'search' => _("Search")), - 'desc' => _("Select the view to display after login:") -); - -// Load constants from lib/Skoli.php -require_once dirname(__FILE__) . '/../lib/Skoli.php'; - -// columns in the class list view -$_prefs['class_columns'] = array( - 'value' => 'a:6:{i:0;s:13:"semesterstart";i:1;s:11:"semesterend";i:2;s:5:"grade";i:3;s:8:"semester";i:4;s:8:"location";i:5;s:8:"category";}', - 'locked' => false, - 'shared' => false, - 'type' => 'multienum', - 'enum' => array(SKOLI_SORT_SEMESTERSTART => _("Semester Start"), - SKOLI_SORT_SEMESTEREND => _("Semester End"), - SKOLI_SORT_GRADE => _("Grade"), - SKOLI_SORT_SEMESTER => _("Semester"), - SKOLI_SORT_LOCATION => _("Location"), - SKOLI_SORT_CATEGORY => _("Category")), - 'desc' => _("Select the columns that should be shown in the class list view:") -); - -// user preferred sorting column for classes -$_prefs['sortby_class'] = array( - 'value' => SKOLI_SORT_SEMESTERSTART, - 'locked' => false, - 'shared' => false, - 'type' => 'enum', - 'enum' => array(SKOLI_SORT_SEMESTERSTART => _("Semester Start"), - SKOLI_SORT_SEMESTEREND => _("Semester End"), - SKOLI_SORT_NAME => _("Name"), - SKOLI_SORT_GRADE => _("Grade"), - SKOLI_SORT_SEMESTER => _("Semester"), - SKOLI_SORT_LOCATION => _("Location"), - SKOLI_SORT_CATEGORY => _("Category")), - 'desc' => _("Sort classes by:"), -); - -// user preferred sorting direction for classes -$_prefs['sortdir_class'] = array( - 'value' => SKOLI_SORT_ASCEND, - 'locked' => false, - 'shared' => false, - 'type' => 'enum', - 'enum' => array(SKOLI_SORT_ASCEND => _("Ascending"), - SKOLI_SORT_DESCEND => _("Descending")), - 'desc' => _("Sort direction for classes:"), -); - -// columns in the student list view -$_prefs['student_columns'] = array( - 'value' => 'a:3:{i:0;s:9:"lastentry";i:1;s:8:"summarks";i:2;s:11:"sumabsences";}', - 'locked' => false, - 'shared' => false, - 'type' => 'multienum', - 'enum' => array(SKOLI_SORT_LASTENTRY => _("Last Entry"), - SKOLI_SORT_SUMMARKS => _("Mark average"), - SKOLI_SORT_SUMABSENCES => _("Absences")), - 'desc' => _("Select the columns that should be shown in the student list view:") -); - -// user preferred sorting column for students -$_prefs['sortby_student'] = array( - 'value' => SKOLI_SORT_NAME, - 'locked' => false, - 'shared' => false, - 'type' => 'enum', - 'enum' => array(SKOLI_SORT_NAME => _("Name"), - SKOLI_SORT_LASTENTRY => _("Last Entry"), - SKOLI_SORT_SUMMARKS => _("Mark average"), - SKOLI_SORT_SUMABSENCES => _("Absences")), - 'desc' => _("Sort students by:"), -); - -// user preferred sorting direction for students -$_prefs['sortdir_student'] = array( - 'value' => SKOLI_SORT_ASCEND, - 'locked' => false, - 'shared' => false, - 'type' => 'enum', - 'enum' => array(SKOLI_SORT_ASCEND => _("Ascending"), - SKOLI_SORT_DESCEND => _("Descending")), - 'desc' => _("Sort direction for students:"), -); - -// preference for wrapping the details for an entry. -$_prefs['entry_details_wrap'] = array( - 'value' => 100, - 'locked' => false, - 'shared' => false, - 'type' => 'number', - 'desc' => _("How many characters of the entry details in search view should we allow to see?") -); - -// preference for contact lists. -$_prefs['contact_list'] = array( - 'value' => 'ask', - 'locked' => false, - 'shared' => false, - 'type' => 'enum', - 'enum' => array('ask' => _("Ask every time"), - 'none' => _("Don't create contact lists"), - 'auto' => _("Automatically create a new contact list")), - 'desc' => _("When a new class is created should we also create a new contact list?") -); - -// template for new contact lists. -$_prefs['contact_list_name'] = array( - 'value' => "%c - %g - %s", - 'locked' => false, - 'shared' => false, - 'type' => 'text', - 'desc' => _("Enter a default name for new contact lists.
    NOTE: You can use %c, %g or %s as substitution for the class, grade respectively semester name.") -); - -// preference for rounding marks. -$_prefs['marks_roundby'] = array( - 'value' => 2, - 'locked' => false, - 'shared' => false, - 'type' => 'number', - 'desc' => _("How many decimal digits should we round marks to?") -); - -// custom settings for marks -$_prefs['marks_format_custom'] = array( - 'value' => "6, 5.5, 5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1", - 'locked' => false, - 'shared' => false, - 'type' => 'text', - 'desc' => _("Enter some custom marks and separate them by comma (best mark first).
    NOTE: You also need to choose \"Custom settings\" above.") -); - -/** - * Hidden preferences - */ - -// show the class list options panel? -// a value of 0 = no, 1 = yes -$_prefs['show_panel'] = array( - 'value' => 1, - 'locked' => false, - 'shared' => false, - 'type' => 'checkbox', - 'desc' => _("Show class list options panel?") -); - -// show students in the class list view? -$_prefs['show_students'] = array( - 'value' => 1, - 'locked' => false, - 'shared' => false, - 'type' => 'checkbox', - 'desc' => _("Show students in the class list?"), -); - -// store the class lists to diplay -$_prefs['display_classes'] = array( - 'value' => 'a:0:{}', - 'locked' => false, - 'shared' => false, - 'type' => 'implicit' -); - -// store the last object format when adding a new entry -$_prefs['default_objects_format'] = array( - 'value' => 'mark', - 'locked' => false, - 'shared' => false, - 'type' => 'implicit' -); diff --git a/skoli/config/schools.php.dist b/skoli/config/schools.php.dist deleted file mode 100644 index 6d3debd57..000000000 --- a/skoli/config/schools.php.dist +++ /dev/null @@ -1,114 +0,0 @@ - _("Custom school") -); - -/** - * The following school may be used for primary schools in Bern, Switzerland. - */ -$cfgSchools['prim_be'] = array( - 'title' => _("Sample school"), - 'grade' => array( - _("1. class"), - _("2. class"), - _("3. class"), - _("4. class"), - _("5. class"), - _("6. class") - ), - 'semester' => array( - array( - 'name' => _("1. term"), - 'start' => 'W33-1', - 'end' => 'W05-5' - ), - array( - 'name' => _("2. term"), - 'start' => 'W07-1', - 'end' => 'W27-5' - ) - ), - 'location' => array( - _("Schoolhouse 1"), - _("Schoolhouse 2") - ), - 'marks' => '6, 5.5, 5, 4.5, 4, 3.5, 3, 2.5, 2, 1.5, 1', - 'subjects' => array( - _("German") => array( - _("Hearing and Talking"), - _("Reading"), - _("Writing"), - ), - _("Mathematics") => array( - _("Imagination"), - _("Skills"), - _("Appliance"), - _("Problem solving behavior"), - ), - _("Nature-Human-Environment"), - _("Music"), - _("Sport"), - _("Construct"), - _("French") => array( - _("Hearing"), - _("Talking"), - _("Reading"), - _("Writing"), - ), - _("English") => array( - _("Hearing"), - _("Talking"), - _("Reading"), - _("Writing"), - ), - ), - 'objectives' => array( - _("Motivation to learn and dedication"), - _("Concentration, attention, perseverance"), - _("Exercise processing"), - _("Teamwork and autonomy"), - ), -); diff --git a/skoli/data.php b/skoli/data.php deleted file mode 100644 index 570fac76e..000000000 --- a/skoli/data.php +++ /dev/null @@ -1,178 +0,0 @@ - - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -if (!$conf['menu']['export']) { - Horde::url('list.php', true)->redirect(); -} - -$classes = Skoli::listClasses(); - -/* If there are no valid classes, abort. */ -if (count($classes) == 0) { - $notification->push(_("No classes are currently available. Export is disabled."), 'horde.error'); - require SKOLI_TEMPLATES . '/common-header.inc'; - require SKOLI_TEMPLATES . '/menu.inc'; - require $registry->get('templates', 'horde') . '/common-footer.inc'; - exit; -} - -$class_options = array(); -foreach ($classes as $key=>$class) { - $class_options[] = '\n"; -} - -$wholeclass_option = '\n"; -$student_options = array(); -$student_options[] = $wholeclass_option; -if (Horde_Util::getFormData('class') != '') { - $class = Horde_Util::getFormData('class'); -} else { - reset($classes); - $class = key($classes); -} -$export_class = current(Skoli::listStudents($class, SKOLI_SORT_NAME, SKOLI_SORT_ASCEND)); -foreach ($export_class['_students'] as $address) { - $student_options[] = '\n"; -} - -$actionID = Horde_Util::getFormData('actionID'); - -/* Loop through the action handlers. */ -switch ($actionID) { -case 'export': - $data = array(); - $driver = &Skoli_Driver::singleton($class); - if (Horde_Util::getFormData('student') == 'all') { - /* Export whole class. */ - $subjects = $driver->getSubjects('mark'); - foreach ($export_class['_students'] as $student) { - $row = array(); - $row[_("Class")] = $export_class['name']; - $row[_("Firstname")] = $student['firstname']; - $row[_("Lastname")] = $student['lastname']; - - /* Absences */ - $absences = Skoli::sumAbsences($class, $student['student_id']); - $row[_("Excused absences")] = $absences[0]; - $row[_("Absences without valid excuse")] = $absences[1]; - - /* Marks */ - foreach ($subjects as $subject) { - $row[$subject] = Skoli::sumMarks($class, $student['student_id'], $subject); - } - - /* Outcomes */ - $outcomes = Skoli::sumOutcomes($class, $student['student_id']); - $row[_("Completed outcomes")] = $outcomes[0]; - $row[_("Open outcomes")] = $outcomes[1]; - - $data[] = $row; - } - /* Make sure that only columns with data are exportet. */ - if (count($data)) { - foreach ($data[0] as $key=>$value) { - $emptycolumn = true; - foreach ($data as $row) { - if ($row[$key] !== '') { - $emptycolumn = false; - break; - } - } - if ($emptycolumn) { - foreach ($data as $rowkey=>$row) { - unset($data[$rowkey][$key]); - } - } - } - } - } else { - /* Export all entries for the selected student. */ - $data[] = array(_("Marks")); - $subjects = $driver->getSubjects('mark'); - foreach ($subjects as $subject) { - $params = array(array('name' => 'subject', 'value' => $subject, 'strict' => 1)); - $marks = Skoli::listEntries($class, Horde_Util::getFormData('student'), 'mark', $params, SKOLI_SORT_DATE, SKOLI_SORT_DESCEND); - foreach ($marks as $mark) { - $data[] = array($subject, $mark['date'], $mark['title'], Skoli::convertNumber($mark['mark']), Skoli::convertNumber($mark['weight'])); - } - } - - $data[] = array(_("Objectives")); - $subjects = $driver->getSubjects('objective'); - foreach ($subjects as $subject) { - $params = array(array('name' => 'subject', 'value' => $subject, 'strict' => 1)); - $objectives = Skoli::listEntries($class, Horde_Util::getFormData('student'), 'objective', $params, SKOLI_SORT_DATE, SKOLI_SORT_DESCEND); - foreach ($objectives as $objective) { - $data[] = array($subject, $objective['date'], $objective['category'], $objective['objective']); - } - } - - $data[] = array(_("Outcomes")); - $outcomes = Skoli::listEntries($class, Horde_Util::getFormData('student'), 'outcome', null, SKOLI_SORT_DATE, SKOLI_SORT_DESCEND); - foreach ($outcomes as $outcome) { - $completed = isset($outcome['completed']) && $outcome['completed'] != '' ? _("Completed") : _("Open"); - $comment = isset($outcome['comment']) ? $outcome['comment'] : ''; - $data[] = array($outcome['date'], $outcome['outcome'], $completed, $comment); - } - - $data[] = array(_("Absences")); - $absences = Skoli::listEntries($class, Horde_Util::getFormData('student'), 'absence', null, SKOLI_SORT_DATE, SKOLI_SORT_DESCEND); - foreach ($absences as $absence) { - $excused = isset($absence['excused']) && $absence['excused'] != '' ? _("Excused") : _("Not excused"); - $comment = isset($absence['comment']) ? $absence['comment'] : ''; - $data[] = array($absence['date'], Skoli::convertNumber($absence['absence']), $excused, $comment); - } - - /* Make sure that all rows have the same number of columns. */ - $maxcols = 0; - for ($i=0; $i < count($data); $i++) { - if (count($data[$i]) > $maxcols) { - $maxcols = count($data[$i]); - } - } - for ($i=0; $i < count($data); $i++) { - for ($irow=0; $irow < $maxcols; $irow++) { - if (!isset($data[$i][$irow])) { - $data[$i][$irow] = ''; - } - } - } - } - if (!count($data)) { - $notification->push(_("There were no entries to export."), 'horde.message'); - break; - } - - switch (Horde_Util::getFormData('exportID')) { - case EXPORT_CSV: - $injector->getInstance('Horde_Data')->getData('Csv')->exportFile(_("class.csv"), $data, (Horde_Util::getFormData('student') == 'all')); - exit; - - case EXPORT_TSV: - $injector->getInstance('Horde_Data')->getData('Tsv')->exportFile(_("class.tsv"), $data, (Horde_Util::getFormData('student') == 'all')); - exit; - - } - break; -} - -$title = _("Export Classes"); - -Horde::addScriptFile('effects.js', 'horde'); -Horde::addScriptFile('redbox.js', 'horde'); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -require SKOLI_TEMPLATES . '/data/export.inc'; -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/docs/CHANGES b/skoli/docs/CHANGES deleted file mode 100644 index 7e31cfce8..000000000 --- a/skoli/docs/CHANGES +++ /dev/null @@ -1,5 +0,0 @@ ----- -v0.1 ----- - -[xyz] Initial Release diff --git a/skoli/docs/CREDITS b/skoli/docs/CREDITS deleted file mode 100644 index a7551824b..000000000 --- a/skoli/docs/CREDITS +++ /dev/null @@ -1,17 +0,0 @@ -=========================== - Skoli Development Team -=========================== - - -Core Developers -=============== - -- Martin Blumenthal - - -Localization -============ - -===================== ====================================================== -German Martin Blumenthal -===================== ====================================================== diff --git a/skoli/docs/INSTALL b/skoli/docs/INSTALL deleted file mode 100644 index 32a7fd302..000000000 --- a/skoli/docs/INSTALL +++ /dev/null @@ -1,241 +0,0 @@ -====================== - Installing Skoli 0.1 -====================== - -:Contact: horde@lists.horde.org - -.. contents:: Contents -.. section-numbering:: - -This document contains instructions for installing the Skoli administrative -application for teachers on your system. - -For information on the capabilities and features of Skoli, see the file -README_ in the top-level directory of the Skoli distribution. - - -Obtaining Skoli -================== - -Skoli can be obtained from the Horde website and FTP server, at - - http://www.horde.org/skoli/ - - ftp://ftp.horde.org/pub/skoli/ - -Or use the mirror closest to you: - - http://www.horde.org/mirrors.php - -Bleeding-edge development versions of Skoli are available via CVS; see the -file `docs/HACKING`_ in the Horde distribution, or the website -http://www.horde.org/source/, for information on accessing the Horde CVS -repository. - - -Prerequisites -============= - -To function properly, Skoli **requires** the following: - -1. A working Horde installation. - - Skoli runs within the `Horde Application Framework`_, a set of common - tools for Web applications written in PHP. You must install Horde before - installing Skoli. - - .. Important:: Skoli 0.1 requires version 3.0+ of the Horde Framework - - earlier versions of Horde will **not** work. - - .. _`Horde Application Framework`: http://www.horde.org/horde/ - - The Horde Framework can be obtained from the Horde website and FTP server, - at - - http://www.horde.org/horde/ - - ftp://ftp.horde.org/pub/horde/ - - Many of Skoli's prerequisites are also Horde prerequisites. - - .. Important:: Be sure to have completed all of the steps in the - `horde/docs/INSTALL`_ file for the Horde Framework before - installing Skoli. - -2. SQL support in PHP. - - Skoli stores its data in an SQL database. Build PHP with whichever SQL - driver you require; see the Horde INSTALL_ file for details. - -3. Turba, the Horde contacts manager. - - Turba is the Horde contact management application, designed to be - integrated with other Horde applications to provide a unified interface to - contact management throughout the Horde suite. - - Turba is available from: - - http://www.horde.org/turba/ - - ftp://ftp.horde.org/pub/turba/ - - Turba provides a local address book and an LDAP directory search function - to IMP. - - You must use the 2.x branch of Turba with Skoli 0.1. - - -Installing Skoli -================ - -Skoli is written in PHP, and must be installed in a web-accessible -directory. The precise location of this directory will differ from system to -system. Conventionally, Skoli is installed directly underneath Horde in the -web server's document tree. - -Since Skoli is written in PHP, there is no compilation necessary; simply -expand the distribution where you want it to reside and rename the root -directory of the distribution to whatever you wish to appear in the URL. For -example, with the Apache web server's default document root of -``/usr/local/apache/htdocs``, you would type:: - - cd /usr/local/apache/htdocs/horde - tar zxvf /path/to/skoli-x.y.z.tar.gz - mv skoli-x.y.z skoli - -and would then find Skoli at the URL:: - - http://your-server/horde/skoli/ - - -Configuring Skoli -==================== - -1. Configuring Horde for Skoli - - a. Register the application - - In ``horde/config/registry.php``, find the ``applications['skoli']`` - stanza. The default settings here should be okay, but you can change - them if desired. If you have changed the location of Skoli relative - to Horde, either in the URL, in the filesystem or both, you must update - the ``fileroot`` and ``webroot`` settings to their correct values. - - If Skoli is not yet present in ``horde/config/registry.php`` you can - use something like: - - $this->applications['skoli'] = array( - 'fileroot' => dirname(__FILE__) . '/../skoli', - 'webroot' => $this->applications['horde']['webroot'] . '/skoli', - 'name' => _("School"), - 'status' => 'active', - 'menu_parent' => 'office' - ); - - $this->applications['skoli-menu'] = array( - 'status' => 'block', - 'app' => 'skoli', - 'blockname' => 'tree_menu', - 'menu_parent' => 'skoli', - ); - -2. Creating the database tables - - The specific steps to create Skoli's database tables depend on which - database you've chosen to use. - - First, look in ``scripts/sql/`` to see if a script already exists for your - database type. If so, you should be able to simply execute that script as - superuser in your database. (Note that executing the script as the "horde" - user will probably fail when granting privileges.) - - If such a script does not exist, you'll need to build your own, using the - file ``skoli.sql`` as a starting point. If you need assistance in - creating database tables, you may wish to let us know on the Skoli - mailing list. - -3. Configuring Skoli - - To configure Skoli, change to the ``config/`` directory of the installed - distribution, and make copies of all of the configuration ``dist`` files - without the ``dist`` suffix:: - - cd config/ - for foo in *.dist; do cp $foo `basename $foo .dist`; done - - Or on Windows:: - - copy *.dist *. - - Documentation on the format and purpose of those files can be found in each - file. You may edit these files if you wish to customize Skoli's - appearance and behavior. With one exception (``foo.php``) the defaults will - be correct for most sites. - - You must login to Horde as a Horde Administrator to finish the - configuration of Skoli. Use the Horde ``Administration`` menu item to - get to the administration page, and then click on the ``Configuration`` - icon to get the configuration page. Select ``Skoli Name`` from the - selection list of applications. Fill in or change any configuration values - as needed. When done click on ``Generate Skoli Name Configuration`` to - generate the ``conf.php`` file. If your web server doesn't have write - permissions to the Skoli configuration directory or file, it will not be - able to write the file. In this case, go back to ``Configuration`` and - choose one of the other methods to create the configuration file - ``skoli/config/conf.php``. - - Note for international users: Skoli uses GNU gettext to provide local - translations of text displayed by applications; the translations are found - in the ``po/`` directory. If a translation is not yet available for your - locale (and you wish to create one), see the ``horde/po/README`` file, or - if you're having trouble using a provided translation, please see the - `horde/docs/TRANSLATIONS`_ file for instructions. - -4. School templates - - To customize your school edit the file ``skoli/config/school.php``. It - contains some examples you can start from. - -5. Testing Skoli - - Use Skoli to create a class and add some entries. Test at least the - following: - - - Creating a new Class - - Adding a new entry for each desired type - - Modifying an entry - - Deleting an entry - - -Obtaining Support -================= - -If you encounter problems with Skoli, help is available! - -The Horde Frequently Asked Questions List (FAQ), available on the Web at - - http://www.horde.org/faq/ - -The Horde Project runs a number of mailing lists, for individual applications -and for issues relating to the project as a whole. Information, archives, and -subscription information can be found at - - http://www.horde.org/mail/ - -Lastly, Horde developers, contributors and users may also be found on IRC, -on the channel #horde on the Freenode Network (irc.freenode.net). - -Please keep in mind that Skoli is free software written by volunteers. -For information on reasonable support expectations, please read - - http://www.horde.org/support.php - -Thanks for using Skoli! - -The Skoli team - - -.. _README: ?f=README.html -.. _`horde/docs/HACKING`: ../../horde/docs/?f=HACKING.html -.. _`horde/docs/INSTALL`: ../../horde/docs/?f=INSTALL.html -.. _`horde/docs/TRANSLATIONS`: ../../horde/docs/?f=TRANSLATIONS.html diff --git a/skoli/docs/RELEASE_NOTES b/skoli/docs/RELEASE_NOTES deleted file mode 100644 index c49e37af4..000000000 --- a/skoli/docs/RELEASE_NOTES +++ /dev/null @@ -1,52 +0,0 @@ -notes['fm']['focus'] = 4; - -/* Mailing list release notes. */ -$this->notes['ml']['changes'] = <<notes['fm']['changes'] = <<notes['name'] = 'Skoli'; -$this->notes['fm']['project'] = 'skoli'; -$this->notes['fm']['branch'] = 'Default'; diff --git a/skoli/docs/TODO b/skoli/docs/TODO deleted file mode 100644 index 470eab49e..000000000 --- a/skoli/docs/TODO +++ /dev/null @@ -1,13 +0,0 @@ -============================= - Skoli Development TODO List -============================= - -:Contact: horde@lists.horde.org - -- When adding new entries allow users to add different values for more than one student (e.g. adding marks for the whole class) - -- Tune up the search form with type dependent options (e.g. drop-down with used subjects). - -- Implement an easy form to create timetables in e.g. Kronolith. - -- Allow users to search for an address to add to classes (e.g. like the compose addressbook window in imp). diff --git a/skoli/entry.php b/skoli/entry.php deleted file mode 100644 index 20e18e283..000000000 --- a/skoli/entry.php +++ /dev/null @@ -1,118 +0,0 @@ - - */ - -@define('SKOLI_BASE', dirname(__FILE__)); -require_once SKOLI_BASE . '/lib/base.php'; - -// Exit if this isn't an authenticated user. -if (!$GLOBALS['registry']->getAuth()) { - Horde::url('list.php', true)->redirect(); -} - -$vars = Horde_Variables::getDefaultVariables(); -$driver = &Skoli_Driver::singleton(); -$entry = $driver->getEntry($vars->get('entry')); -if (is_a($entry, 'PEAR_Error') || !count($entry)) { - $notification->push(_("Entry not found."), 'horde.error'); - Horde::url('search.php', true)->redirect(); -} -$share = $GLOBALS['skoli_shares']->getShare($entry['class_id']); - -// Check permissions -if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ)) { - $notification->push(_("You are not allowed to view this entry."), 'horde.error'); - Horde::url('search.php', true) - ->add('actionID', 'search') - ->redirect(); -} - -$studentdetails = Skoli::getStudent($share->get('address_book'), $entry['student_id']); - -// Get view. -$viewName = Horde_Util::getFormData('view', 'Entry'); - -if ($viewName != 'DeleteEntry') { - require_once SKOLI_BASE . '/lib/Forms/Entry.php'; - if (!$vars->exists('class_id')) { - foreach ($entry as $key=>$val) { - if (!is_array($val)) { - $vars->set($key, $val); - } - } - foreach ($entry['_attributes'] as $key=>$val) { - $vars->set('attribute_' . $key, $val); - } - } - $form = new Skoli_EntryForm($vars); - if ($viewName == 'EditEntry') { - if ($form->validate($vars)) { - $driver = &Skoli_Driver::singleton($vars->get('class_id')); - $result = $driver->updateEntry($entry['object_id'], $vars); - if (is_a($result, 'PEAR_Error')) { - $notification->push(sprintf(_("Couldn't update this entry: %s"), $result->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("The entry for \"%s\" has been saved."), $studentdetails[$conf['addresses']['name_field']]), 'horde.success'); - Horde::url('search.php', true) - ->add('actionID', 'search') - ->redirect(); - } - } - } -} - -// Entry actions. -$actionID = Horde_Util::getFormData('actionID'); -if ($actionID == 'delete') { - if (is_a($deleted = $driver->deleteEntry($entry['object_id']), 'PEAR_Error')) { - $notification->push(sprintf(_("There was an error deleting this entry: %s"), $deleted->getMessage()), 'horde.error'); - } else { - $notification->push(sprintf(_("The entry for \"%s\" has been deleted."), $studentdetails[$conf['addresses']['name_field']]), 'horde.success'); - Horde::url('search.php', true) - ->add('actionID', 'search') - ->redirect(); - } -} - -// Get tabs. -$url = Horde_Util::addParameter(Horde::url('entry.php'), 'entry', $entry['object_id']); -$tabs = new Horde_Core_Ui_Tabs('view', $vars); -$tabs->addTab(_("View"), $url, array('tabname' => 'Entry', 'id' => 'tabEntry')); -if ($share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) { - $tabs->addTab(_("Edit"), $url, array('tabname' => 'EditEntry', 'id' => 'tabEditEntry')); -} -if ($share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE)) { - $tabs->addTab(_("Delete"), $url, array('tabname' => 'DeleteEntry', 'id' => 'tabDeleteEntry')); -} - -$title = _("Edit Entry"); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; - -echo '
    '; -echo $tabs->render($viewName); -echo '

    ' . sprintf(_("Entry for \"%s\""), $studentdetails[$conf['addresses']['name_field']]) . '

    '; - -// View output -switch ($viewName) { -case 'Entry': - echo $form->renderInactive($form->getRenderer(), $vars); - break; - -case 'EditEntry': - echo $form->renderActive($form->getRenderer(), $vars, 'entry.php', 'post'); - break; - -case 'DeleteEntry': - require SKOLI_TEMPLATES . '/entry/delete.inc'; - break; -} - -echo '
    '; -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/index.php b/skoli/index.php deleted file mode 100644 index c5a7d4085..000000000 --- a/skoli/index.php +++ /dev/null @@ -1,10 +0,0 @@ -getValue('initial_page') . '.php'; diff --git a/skoli/lib/Ajax/Application.php b/skoli/lib/Ajax/Application.php deleted file mode 100644 index 6d3096011..000000000 --- a/skoli/lib/Ajax/Application.php +++ /dev/null @@ -1,15 +0,0 @@ - - * @category Horde - * @license http://www.fsf.org/copyleft/gpl.html GPL - * @package Skoli - */ -class Skoli_Ajax_Application extends Horde_Core_Ajax_Application {} diff --git a/skoli/lib/Application.php b/skoli/lib/Application.php deleted file mode 100644 index d21b77b78..000000000 --- a/skoli/lib/Application.php +++ /dev/null @@ -1,16 +0,0 @@ - 0) { - $tree->addNode( - $parent . '__new', - $parent, - _("New Entry"), - $indent + 1, - false, - array( - 'icon' => $add_img, - 'url' => $add - ) - ); - - foreach ($classes as $name => $class) { - $tree->addNode( - $parent . $name . '__new', - $parent . '__new', - sprintf(_("in %s"), $class->get('name')), - $indent + 2, - false, - array( - 'icon' => $add_img, - 'url' => $add->copy()->add('class', $name) - ) - ); - } - - $tree->addNode( - $parent . '__search', - $parent, - _("Search"), - $indent + 1, - false, - array( - 'icon' => Horde_Themes::img('search.png'), - 'url' => Horde::url('search.php') - ) - ); - } - } - -} diff --git a/skoli/lib/Driver.php b/skoli/lib/Driver.php deleted file mode 100644 index 279f9b98e..000000000 --- a/skoli/lib/Driver.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @package Skoli - */ -class Skoli_Driver { - - /** - * String containing the current class name. - * - * @var string - */ - var $_class = ''; - - /** - * An error message to throw when something is wrong. - * - * @var string - */ - var $_errormsg; - - /** - * Constructor - All real work is done by initialize(). - */ - function Skoli_Driver($errormsg = null) - { - if (is_null($errormsg)) { - $this->_errormsg = _("The School backend is not currently available."); - } else { - $this->_errormsg = $errormsg; - } - } - - /** - * Attempts to return a concrete Skoli_Driver instance based on $driver. - * - * @param string $class The name of the class to load. - * - * @param string $driver The type of the concrete Skoli_Driver subclass - * to return. The class name is based on the - * storage driver ($driver). The code is - * dynamically included. - * - * @param array $params A hash containing any additional configuration - * or connection parameters a subclass might need. - * - * @return Skoli_Driver The newly created concrete Skoli_Driver - * instance, or false on an error. - */ - function &factory($class = '', $driver = null, $params = null) - { - /* Check if we have access to the given class */ - static $classes; - if (!is_array($classes)) { - $classes = Skoli::listClasses(); - } - if ($class != '' && !isset($classes[$class])) { - $class = new Skoli_Driver(sprintf(_("Access for class \"%s\" is denied"), $class)); - return $class; - } - - if (is_null($driver)) { - $driver = $GLOBALS['conf']['storage']['driver']; - } - $driver = basename($driver); - - if (is_null($params)) { - $params = Horde::getDriverConfig('storage', $driver); - } - - require_once dirname(__FILE__) . '/Driver/' . $driver . '.php'; - $objclass = 'Skoli_Driver_' . $driver; - if (class_exists($objclass)) { - $class = new $objclass($class, $params); - $result = $class->initialize(); - if (is_a($result, 'PEAR_Error')) { - $class = new Skoli_Driver(sprintf(_("The School backend is not currently available: %s"), $result->getMessage())); - } - } else { - $class = new Skoli_Driver(sprintf(_("Unable to load the definition of %s."), $objclass)); - } - - return $class; - } - - /** - * Attempts to return a reference to a concrete Skoli_Driver - * instance based on $driver. It will only create a new instance - * if no Skoli_Driver instance with the same parameters currently - * exists. - * - * This should be used if multiple storage sources are required. - * - * This method must be invoked as: $var = &Skoli_Driver::singleton() - * - * @param string $class The name of the class to load. - * - * @param string $driver The type of concrete Skoli_Driver subclass - * to return. The is based on the storage - * driver ($driver). The code is dynamically - * included. - * - * @param array $params (optional) A hash containing any additional - * configuration or connection parameters a - * subclass might need. - * - * @return mixed The created concrete Skoli_Driver instance, or false - * on error. - */ - function &singleton($class = '', $driver = null, $params = null) - { - static $instances = array(); - - if (is_null($driver)) { - $driver = $GLOBALS['conf']['storage']['driver']; - } - - if (is_null($params)) { - $params = Horde::getDriverConfig('storage', $driver); - } - - $signature = serialize(array($class, $driver, $params)); - if (!isset($instances[$signature])) { - $instances[$signature] = &Skoli_Driver::factory($class, $driver, $params); - } - - return $instances[$signature]; - } - -} diff --git a/skoli/lib/Driver/sql.php b/skoli/lib/Driver/sql.php deleted file mode 100644 index a63cfa8e4..000000000 --- a/skoli/lib/Driver/sql.php +++ /dev/null @@ -1,605 +0,0 @@ - - * 'objects_table' The name of the objects table in 'database'. - * Default is 'skoli_objects'. - * 'object_attributes_table' The name of the attributes table in 'database'. - * Default ist 'skoli_object_attributes'. - * 'students_table' The name of the students table in 'database'. - * Default is 'skoli_classes_students'. - * - * The table structure can be created by the scripts/sql/skoli.sql script. - * - * See the enclosed file COPYING for license information (GPL). If you - * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. - * - * @author Martin Blumenthal - * @package Skoli - */ -class Skoli_Driver_sql extends Skoli_Driver { - - /** - * Handle for the current database connection. - * - * @var DB - */ - var $_db; - - /** - * Handle for the current database connection, used for writing. Defaults - * to the same handle as $_db if a separate write database is not required. - * - * @var DB - */ - var $_write_db; - - /** - * Constructs a new SQL storage object. - * - * @param string $classlist The classlist to load. - * @param array $params A hash containing connection parameters. - */ - function Skoli_Driver_sql($class, $params = array()) - { - $this->_class = $class; - $this->_params = $params; - } - - /** - * Attempts to open a connection to the SQL server. - * - * @return boolean True on success, PEAR_Error on failure. - */ - function initialize() - { - try { - $this->_db = $GLOBALS['injector']->getInstance('Horde_Db_Pear')->getDb('read', 'skoli', 'storage'); - $this->_write_db = $GLOBALS['injector']->getInstance('Horde_Db_Pear')->getDb('rw', 'skoli', 'storage'); - } catch (Horde_Exception $e) { - return PEAR::raiseError($e->getMessage()); - } - - $this->_params = array_merge(array( - 'objects_table' => 'skoli_objects', - 'object_attributes_table' => 'skoli_object_attributes', - 'students_table' => 'skoli_classes_students' - ), $this->_params); - - return true; - } - - /** - * Get all students from the backend storage. - * - * @return array List with all student IDs. - */ - function getStudents() - { - $query = 'SELECT student_id FROM ' . $this->_params['students_table'] . - ' WHERE class_id = ?'; - $values = array($this->_class); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::getStudents(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $students = $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC); - - /* Return an error immediately if the query failed. */ - if (is_a($students, 'PEAR_Error')) { - Horde::logMessage($students, 'ERR'); - return $students; - } - - return $students; - } - - /** - * Add students to the backend storage. - * - * @param array $students List with students. - * - * @return boolean True on success, PEAR_Error on failure. - */ - function addStudents($students) - { - /* Delete any existing Students */ - $query = 'DELETE FROM ' . $this->_params['students_table'] . - ' WHERE class_id=?'; - $result = $this->_write_db->query($query, array($this->_class)); - - foreach ($students as $addressid) { - $query = 'INSERT INTO ' . $this->_params['students_table'] . - ' (class_id, student_id)' . - ' VALUES (?, ?)'; - $values = array($this->_class, $addressid); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::addStudents(): %s', $query), 'DEBUG'); - - /* Attempt the insertion query. */ - $result = $this->_write_db->query($query, $values); - - /* Return an error immediately if the query failed. */ - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } - - return true; - } - - /** - * Get an entry from the backend storage. - * - * @param string $entryid The entry ID. - * - * @return array List with all entry fields. - */ - function getEntry($entryid) - { - $query = 'SELECT * FROM ' . $this->_params['objects_table'] . - ' WHERE object_id = ?'; - $values = array($entryid); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::getEntry(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $entry = $this->_db->getRow($query, $values, DB_FETCHMODE_ASSOC); - - /* Return an error immediately if the query failed. */ - if (is_a($entry, 'PEAR_Error')) { - Horde::logMessage($entry, 'ERR'); - return $entry; - } else if (!is_array($entry)) { - return array(); - } - - $query = 'SELECT * FROM ' . $this->_params['object_attributes_table'] . - ' WHERE object_id = ?'; - $values = array($entryid); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::getEntry(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $attributes = $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC); - - /* Return an error immediately if the query failed. */ - if (is_a($attributes, 'PEAR_Error')) { - Horde::logMessage($attributes, 'ERR'); - return $attributes; - } - - $entry['_attributes'] = array(); - foreach ($attributes as $attribute) { - $entry['_attributes'][$attribute['attr_name']] = $attribute['attr_value']; - } - - if (empty($this->_class)) { - $this->_class = $entry['class_id']; - } - - return $entry; - } - - /** - * Get all entries for the current class or student from the backend storage. - * - * @param string $studentid The student ID. - * - * @param string $type The entry type to search in. - * - * @param array $searchparams Some additional search parameters. - * - * @return array List with all entries. - */ - function getEntries($studentid = null, $type = null, $searchparams = array()) - { - if (is_null($studentid)) { - $students = $this->getStudents(); - } else { - $students = array(array('student_id' => $studentid)); - } - - foreach ($students as $studentkey=>$student) { - /* Build the search parameter */ - if (count($searchparams)) { - $where = ''; - $search_values = array(); - if (count($searchparams) === 1 && !is_array($searchparams[0])) { - /* search all attributes for the specified text */ - $where = ' AND a.attr_value LIKE ?'; - $search_values[] = '%' . $searchparams[0] . '%'; - } else { - /* search only in the specified fields */ - $where = ' AND '; - for ($i = 0; $i < count($searchparams); $i++) { - $strict = !empty($searchparams[$i]['strict']); - $where .= '(a.attr_name = ? AND a.attr_value ' . ($strict ? '=' : 'LIKE') . ' ?) OR '; - $search_values[] = $searchparams[$i]['name']; - if ($strict) { - $search_values[] = $searchparams[$i]['value']; - } else { - $search_values[] = '%' . $searchparams[$i]['value'] . '%'; - } - } - $where = substr($where, 0, -4); - } - $query = 'SELECT o.* FROM ' . $this->_params['object_attributes_table'] . ' AS a, ' . - $this->_params['objects_table'] . ' AS o' . - ' WHERE o.object_id = a.object_id AND o.class_id = ? AND o.student_id = ?' . (!is_null($type) ? ' AND o.object_type = ?' : '') . $where . - ' GROUP BY o.object_id'; - $values = array($this->_class, $student['student_id']); - if (!is_null($type)) { - $values[] = $type; - } - $values = array_merge($values, $search_values); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::getEntries(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $entries = $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC); - - /* Return an error immediately if the query failed. */ - if (is_a($entries, 'PEAR_Error')) { - Horde::logMessage($entries, 'ERR'); - return $entries; - } - } else { - $query = 'SELECT * FROM ' . $this->_params['objects_table'] . - ' WHERE class_id = ? AND student_id = ?' . - (!is_null($type) ? ' AND object_type = ?' : ''); - $values = array($this->_class, $student['student_id']); - if (!is_null($type)) { - $values[] = $type; - } - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::getEntries(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $entries = $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC); - - /* Return an error immediately if the query failed. */ - if (is_a($entries, 'PEAR_Error')) { - Horde::logMessage($entries, 'ERR'); - return $entries; - } - } - - $students[$studentkey]['_entries'] = $entries; - - foreach ($entries as $entrykey=>$entry) { - $query = 'SELECT * FROM ' . $this->_params['object_attributes_table'] . - ' WHERE object_id = ?'; - $values = array($entry['object_id']); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::getEntries(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $attributes = $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC); - - /* Return an error immediately if the query failed. */ - if (is_a($attributes, 'PEAR_Error')) { - Horde::logMessage($attributes, 'ERR'); - return $attributes; - } - - $students[$studentkey]['_entries'][$entrykey]['_attributes'] = array(); - foreach ($attributes as $attribute) { - $students[$studentkey]['_entries'][$entrykey]['_attributes'][$attribute['attr_name']] = $attribute['attr_value']; - } - } - } - - return $students; - } - - /** - * Get the timestamp of the last entry for the given student. - * - * @param string $studentid The student ID. - * - * @return int The last entry. - */ - function lastEntry($studentid) - { - $query = 'SELECT object_time FROM ' . $this->_params['objects_table'] . - ' WHERE class_id = ? AND student_id = ? ORDER BY object_time DESC'; - $values = array($this->_class, $studentid); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::lastEntry(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $lastentry = $this->_db->limitQuery($query, 0, 1); - $lastentry = $lastentry->fetchRow(DB_FETCHMODE_ORDERED); - - /* Return an error immediately if the query failed. */ - if (is_a($lastentry, 'PEAR_Error')) { - Horde::logMessage($lastentry, 'ERR'); - return $lastentry; - } - - if (count($lastentry)) { - return $lastentry[0]; - } - - return null; - } - - /** - * Add or update a new entry to the backend storage. - * - * @param string $entryid The entry ID. - * - * @param Variables $vars List with form variables. - * - * @return boolean True on success, PEAR_Error on failure. - */ - function updateEntry($entryid, $vars) - { - $attributes = array(); - foreach ($vars->_vars as $key=>$value) { - if (strpos($key, 'attribute_') === 0 && $value != '') { - $attribute = substr($key, 10); - $attributes[$attribute] = $value; - } - } - - $query = 'UPDATE ' . $this->_params['objects_table'] . ' SET' . - ' class_id = ?, student_id = ?, object_time = ?, object_type = ?' . - ' WHERE object_id = ?'; - require_once 'Horde/Date.php'; - $date = new Horde_Date($vars->get('object_time')); - $values = array($this->_class, $vars->get('student_id'), $date->datestamp(), $vars->get('object_type'), $entryid); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::updateEntry(): %s', $query), 'DEBUG'); - - /* Attempt the insertion query. */ - $result = $this->_write_db->query($query, $values); - - /* Return an error immediately if the query failed. */ - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - $query = 'DELETE FROM ' . $this->_params['object_attributes_table'] . - ' WHERE object_id = ?'; - $values = array($entryid); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::updateEntry(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_write_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - foreach ($attributes as $attribute=>$value) { - $query = 'INSERT INTO ' . $this->_params['object_attributes_table'] . - ' (object_id, attr_name, attr_value)' . - ' VALUES (?, ?, ?)'; - $values = array($entryid, $attribute, $value); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::addEntry(): %s', $query), 'DEBUG'); - - /* Attempt the insertion query. */ - $result = $this->_write_db->query($query, $values); - - /* Return an error immediately if the query failed. */ - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } - - return true; - } - - /** - * Add a new entry to the backend storage. - * - * @param Variables $vars List with form variables. - * - * @return Mixed Studentnames on success, PEAR_Error on failure. - */ - function addEntry($vars) - { - $names = ''; - $class = current(Skoli::listStudents($this->_class)); - - $attributes = array(); - foreach ($vars->_vars as $key=>$value) { - if (strpos($key, 'attribute_') === 0 && $value != '') { - $attribute = substr($key, 10); - $attributes[$attribute] = $value; - } - } - - require_once 'Horde/Date.php'; - foreach ($vars->get('student_id') as $studentid) { - $query = 'INSERT INTO ' . $this->_params['objects_table'] . - ' (object_id, object_owner, object_uid, class_id, student_id, object_time, object_type)' . - ' VALUES (?, ?, ?, ?, ?, ?, ?)'; - $entryId = strval(new Horde_Support_Uuid()); - $date = new Horde_Date($vars->get('object_time')); - $values = array($entryId, $GLOBALS['registry']->getAuth(), strval(new Horde_Support_Uuid()), $this->_class, $studentid, $date->datestamp(), $vars->get('object_type')); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::addEntry(): %s', $query), 'DEBUG'); - - /* Attempt the insertion query. */ - $result = $this->_write_db->query($query, $values); - - /* Return an error immediately if the query failed. */ - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - foreach ($attributes as $attribute=>$value) { - $query = 'INSERT INTO ' . $this->_params['object_attributes_table'] . - ' (object_id, attr_name, attr_value)' . - ' VALUES (?, ?, ?)'; - $values = array($entryId, $attribute, $value); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::addEntry(): %s', $query), 'DEBUG'); - - /* Attempt the insertion query. */ - $result = $this->_write_db->query($query, $values); - - /* Return an error immediately if the query failed. */ - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - } - - $studentdetails = Skoli::getStudent($class['address_book'], $studentid); - $names .= $studentdetails[$GLOBALS['conf']['addresses']['name_field']] . ', '; - } - - return substr($names, 0, -2); - } - - /** - * Get all currently used subjects from the current class. - * - * @param string $type Get subjects only from this type. - * - * @return array List with all subjects. - */ - function getSubjects($type = null) - { - $where = !is_null($type) ? ' AND o.object_type = ?' : ''; - $query = 'SELECT DISTINCT a.attr_value FROM ' . $this->_params['object_attributes_table'] . ' AS a, ' . - $this->_params['objects_table'] . ' AS o' . - ' WHERE a.object_id = o.object_id AND o.class_id = ? AND a.attr_name = ?' . $where; - $values = array($this->_class, 'subject'); - if (!is_null($type)) { - $values[] = $type; - } - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::getSubjects(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $subjects = $this->_db->getAll($query, $values, DB_FETCHMODE_ORDERED); - - /* Return an error immediately if the query failed. */ - if (is_a($subjects, 'PEAR_Error')) { - Horde::logMessage($subjects, 'ERR'); - return $subjects; - } - - $subjectlist = array(); - foreach ($subjects as $subject) { - $subjectlist[] = $subject[0]; - } - - return $subjectlist; - } - - /** - * Deletes all data from the current class. - * - * @return boolean True on success, PEAR_Error on failure. - */ - function deleteAll() - { - $query = 'DELETE FROM ' . $this->_params['students_table'] . - ' WHERE class_id = ?'; - $values = array($this->_class); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::deleteAll(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_write_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - $query = 'SELECT object_id FROM ' . $this->_params['objects_table'] . - ' WHERE class_id = ?'; - $values = array($this->_class); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::deleteAll(): %s', $query), 'DEBUG'); - - /* Attempt the select query. */ - $entries = $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC); - - /* Return an error immediately if the query failed. */ - if (is_a($entries, 'PEAR_Error')) { - Horde::logMessage($entries, 'ERR'); - return $entries; - } - - foreach ($entries as $entry) { - $result = $this->deleteEntry($entry['object_id']); - - /* Return an error immediately if the query failed. */ - if (is_a($result, 'PEAR_Error')) { - return $result; - } - } - - return true; - } - - /** - * Deletes an entry from the current class. - * - * @param string $object_id The entry ID to delete. - * - * @return boolean True on success, PEAR_Error on failure. - */ - function deleteEntry($object_id) - { - $query = 'DELETE FROM ' . $this->_params['objects_table'] . - ' WHERE object_id = ? AND class_id = ?'; - $values = array($object_id, $this->_class); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::deleteEntry(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_write_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - $query = 'DELETE FROM ' . $this->_params['object_attributes_table'] . - ' WHERE object_id = ?'; - $values = array($object_id); - - /* Log the query at a DEBUG log level. */ - Horde::logMessage(sprintf('Skoli_Driver_sql::deleteEntry(): %s', $query), 'DEBUG'); - - /* Attempt the delete query. */ - $result = $this->_write_db->query($query, $values); - - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - return true; - } -} diff --git a/skoli/lib/Forms/CreateClass.php b/skoli/lib/Forms/CreateClass.php deleted file mode 100644 index e930a075c..000000000 --- a/skoli/lib/Forms/CreateClass.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @package Skoli - */ -class Skoli_CreateClassForm extends Horde_Form { - - /** - * Name of the new share. - * - * @var int - */ - var $shareid; - - /** - * List of school properties. - * - * @var array - */ - var $_schoolproperties = array( - 'grade', - 'semester', - 'start', - 'end', - 'location', - 'marks'); - - - function Skoli_CreateClassForm(&$vars) - { - global $conf, $prefs, $registry; - - parent::Horde_Form($vars, _("Create Class")); - - $this->setSection('properties', _("Properties")); - - $this->addVariable(_("General Settings"), null, 'header', false); - - $this->addVariable(_("Name"), 'name', 'text', true); - $this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60)); - - $this->addVariable(_("Category"), 'category', 'category', false); - // A new category doesn't survive a reload action, so reset it - // @TODO: Could this be a bug? - if (strpos($this->_vars->get('category'), '*new*') !== false) { - $this->_vars->set('category', $this->_vars->get('new_category')); - } - - $this->addVariable(_("School Specific Settings"), null, 'header', false); - - // Load Skoli_School - require_once SKOLI_BASE . '/lib/School.php'; - - // List schools - $schoollist = Skoli_School::listSchools(); - $actionvariable = &$this->addVariable(_("Schools"), 'school', 'enum', true, count($schoollist)>1 ? false : true, null, array($schoollist, _("Choose:"))); - if (count($schoollist) > 1) { - require_once 'Horde/Form/Action.php'; - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - } else { - $this->_vars->set('school', key($schoollist)); - } - - // Load the selected school - if ($this->_vars->exists('school')) { - $school = new Skoli_School($this->_vars->get('school')); - foreach ($this->_schoolproperties as $name) { - $school->addFormVariable($this, $name); - } - } - - $this->setSection('students', _("Students")); - - $this->addVariable(_("Address Book"), null, 'header', false); - - $addressbooklist = Skoli_School::listAddressBooks(); - $actionvariable = &$this->addVariable(_("Address Book"), 'address_book', 'enum', true, count($addressbooklist)>1 ? false : true, null, array($addressbooklist, _("Choose:"))); - if (count($addressbooklist) > 1) { - require_once 'Horde/Form/Action.php'; - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - } else { - $this->_vars->set('address_book', key($addressbooklist)); - } - - $this->addVariable(_("Students"), null, 'header', false); - - if ($this->_vars->get('address_book') != '') { - $searchargs = array( - 'addresses' => array(''), - 'addressbooks' => array($this->_vars->get('address_book')), - 'fields' => array() - ); - if ($search_fields_pref = $prefs->getValue('search_fields')) { - foreach (explode("\n", $search_fields_pref) as $s) { - $s = trim($s); - $s = explode("\t", $s); - if (!empty($s[0]) && ($s[0] == $this->_vars->get('address_book'))) { - $searchargs['fields'][array_shift($s)] = $s; - break; - } - } - } - $resultstmp = $registry->call('contacts/search', $searchargs); - // contacts/search seems to return an array entry for each source. - $results = array(); - foreach ($resultstmp as $r) { - $results = array_merge($results, $r); - } - foreach ($results as $address) { - if (isset($address['__type']) && $address['__type'] == 'Object') { - $addresses[$address['__key']] = $address[$conf['addresses']['name_field']]; - } - } - } else { - $addresses = array(); - } - - $this->addVariable(_("Students"), 'students', 'multienum', false, false, null, array($addresses, 20)); - - if ($conf['addresses']['contact_list'] != 'none' && $prefs->getValue('contact_list') != 'none') { - $this->addVariable(_("Contact List"), null, 'header', false); - if ($conf['addresses']['contact_list'] == 'user' && $prefs->getValue('contact_list') == 'ask') { - $this->addVariable(_("Create Contact List?"), 'contact_list_create', 'boolean', true, false); - if (!$this->_vars->exists('contact_list')) { - $this->_vars->set('contact_list_create', true); - } - } - $this->addVariable(_("Name"), 'contact_list', 'text', false, - $conf['addresses']['contact_list'] == 'auto' || $prefs->getValue('contact_list') == 'auto' ? true : false, _("The substitutions %c, %g or %s will be replaced automatically by the class, grade respectively semester name.")); - if (!$this->_vars->exists('contact_list')) { - $contactlist = $conf['addresses']['contact_list'] == 'auto' ? $conf['addresses']['contact_list_name'] : $prefs->getValue('contact_list_name'); - } else { - $contactlist = $this->_vars->get('contact_list'); - } - $this->_vars->set('contact_list', Skoli_School::parseContactListName($contactlist, $this->_vars)); - } - - $this->setButtons(array(_("Create"))); - } - - function execute() - { - global $conf, $prefs, $registry, $notification; - - /* Add new category. */ - if (strpos($this->_vars->get('category'), '*new*') !== false || $this->_vars->get('category') == $this->_vars->get('new_category')) { - $cManager = new Horde_Prefs_CategoryManager(); - $cManager->add($this->_vars->get('new_category')); - $this->_vars->set('category', $this->_vars->get('new_category')); - } - - // Create new share. - $this->shareid = strval(new Horde_Support_Uuid()); - $class = $GLOBALS['skoli_shares']->newShare($this->shareid); - if (is_a($class, 'PEAR_Error')) { - return $class; - } - $class->set('name', $this->_vars->get('name')); - $class->set('desc', $this->_vars->get('description')); - $class->set('category', $this->_vars->get('category')); - $class->set('school', $this->_vars->get('school')); - $class->set('address_book', $this->_vars->get('address_book')); - - require_once 'Horde/Date.php'; - foreach ($this->_schoolproperties as $property) { - if ($property == 'start' || $property == 'end') { - $date = new Horde_Date($this->_vars->get($property)); - $this->_vars->set($property, $date->datestamp()); - } else if ($property == 'marks' && $this->_vars->get($property . '_custom') != '') { - $this->_vars->set($property, $this->_vars->get($property . '_custom')); - } - $class->set($property, $this->_vars->get($property) == '' ? null : $this->_vars->get($property)); - } - - $result = $GLOBALS['skoli_shares']->addShare($class); - - // Save students - if ($this->_vars->exists('students') && $result) { - $driver = &Skoli_Driver::singleton($this->shareid); - $result = $driver->addStudents($this->_vars->get('students')); - if (is_a($result, 'PEAR_Error')) { - $notification->push(_("Couldn't add the selected students to the class."), 'horde.warning'); - } - - // Add new contact list - if ($conf['addresses']['contact_list'] != 'none' && $prefs->getValue('contact_list') != 'none' && $this->_vars->get('contact_list') != '') { - $createlist = true; - if ($conf['addresses']['contact_list'] == 'user' && $prefs->getValue('contact_list') == 'ask' && $this->_vars->get('contact_list_create') == '') { - $createlist = false; - } - } else { - $createlist = false; - } - if ($createlist) { - $apiargs = array( - 'content' => array( - '__type' => 'Group', - '__members' => serialize($this->_vars->get('students')), - 'name' => Skoli_School::parseContactListName($this->_vars->get('contact_list'), $this->_vars, true), - ), - 'contentType' => 'array', - 'source' => $this->_vars->get('address_book') - ); - - try { - $registry->call('contacts/import', $apiargs); - } catch (Horde_Exception $e) { - $notification->push(sprintf(_("Couldn't create the contact list \"%s\"."), $this->_vars->get('contact_list')), 'horde.warning'); - } - } - } - - return $result; - } - -} diff --git a/skoli/lib/Forms/DeleteClass.php b/skoli/lib/Forms/DeleteClass.php deleted file mode 100644 index c0ac3e1ca..000000000 --- a/skoli/lib/Forms/DeleteClass.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @package Skoli - */ -class Skoli_DeleteClassForm extends Horde_Form { - - /** - * Class being deleted - */ - var $_class; - - function Skoli_DeleteClassForm(&$vars, &$class) - { - $this->_class = &$class; - parent::Horde_Form($vars, sprintf(_("Delete %s"), $class->get('name'))); - - $this->addHidden('', 'c', 'text', true); - $this->addVariable(sprintf(_("Really delete the class \"%s\"? This cannot be undone and all data on this class will be permanently removed."), $this->_class->get('name')), 'desc', 'description', false); - - $this->setButtons(array(_("Delete"), _("Cancel"))); - } - - function execute() - { - // If cancel was clicked, return false. - if ($this->_vars->get('submitbutton') == _("Cancel")) { - return false; - } - - if (!$GLOBALS['registry']->getAuth() || - $this->_class->get('owner') != $GLOBALS['registry']->getAuth()) { - return PEAR::raiseError(_("Permission denied")); - } - - // Delete the class. - $storage = &Skoli_Driver::singleton($this->_class->getName()); - $result = $storage->deleteAll(); - if (is_a($result, 'PEAR_Error')) { - return PEAR::raiseError(sprintf(_("Unable to delete \"%s\": %s"), $this->_class->get('name'), $result->getMessage())); - } else { - // Remove share and all groups/permissions. - $result = $GLOBALS['skoli_shares']->removeShare($this->_class); - if (is_a($result, 'PEAR_Error')) { - return $result; - } else { - // Remove class from the display list if it exists - $key = array_search($this->_class->getName(), $GLOBALS['display_classes']); - if ($key !== false) { - unset($GLOBALS['display_classes'][$key]); - $GLOBALS['prefs']->setValue('display_classes', serialize($GLOBALS['display_classes'])); - } - } - } - - return true; - } - -} diff --git a/skoli/lib/Forms/EditClass.php b/skoli/lib/Forms/EditClass.php deleted file mode 100644 index 70812751e..000000000 --- a/skoli/lib/Forms/EditClass.php +++ /dev/null @@ -1,169 +0,0 @@ - - * @package Skoli - */ -class Skoli_EditClassForm extends Horde_Form { - - /** - * Class being edited - */ - var $_class; - - /** - * List of school properties. - * - * @var array - */ - var $_schoolproperties = array( - 'grade', - 'semester', - 'start', - 'end', - 'location', - 'marks'); - - function Skoli_EditClassForm(&$vars, &$class) - { - global $conf, $prefs, $registry; - - $this->_class = &$class; - - parent::Horde_Form($vars, sprintf(_("Edit %s"), $class->get('name'))); - - $this->addHidden('', 'c', 'text', true); - - $this->setSection('properties', _("Properties")); - - $this->addVariable(_("General Settings"), null, 'header', false); - - $this->addVariable(_("Name"), 'name', 'text', true); - $this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60)); - - $this->addVariable(_("Category"), 'category', 'category', false); - - $this->addVariable(_("School Specific Settings"), null, 'header', false); - - // Load Skoli_School - require_once SKOLI_BASE . '/lib/School.php'; - - // List schools - $schoollist = Skoli_School::listSchools(); - $this->addVariable(_("School"), 'school', 'enum', true, true, null, array($schoollist, _("Choose:"))); - - $school = new Skoli_School($this->_vars->get('school')); - foreach ($this->_schoolproperties as $name) { - $school->addFormVariable($this, $name); - } - - $this->setSection('students', _("Students")); - - $this->addVariable(_("Address Book"), null, 'header', false); - - $addressbooklist = Skoli_School::listAddressBooks(true); - $actionvariable = &$this->addVariable(_("Address Book"), 'address_book', 'enum', true, count($addressbooklist)>1 ? false : true, null, array($addressbooklist, _("Choose:"))); - if (count($addressbooklist) > 1) { - require_once 'Horde/Form/Action.php'; - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - } else { - $this->_vars->set('address_book', key($addressbooklist)); - } - - $this->addVariable(_("Students"), null, 'header', false); - - if ($this->_vars->get('address_book') != '') { - $searchargs = array( - 'addresses' => array(''), - 'addressbooks' => array($this->_vars->get('address_book')), - 'fields' => array() - ); - if ($search_fields_pref = $prefs->getValue('search_fields')) { - foreach (explode("\n", $search_fields_pref) as $s) { - $s = trim($s); - $s = explode("\t", $s); - if (!empty($s[0]) && ($s[0] == $this->_vars->get('address_book'))) { - $searchargs['fields'][array_shift($s)] = $s; - break; - } - } - } - $resultstmp = $registry->call('contacts/search', $searchargs); - // contacts/search seems to return an array entry for each source. - $results = array(); - foreach ($resultstmp as $r) { - $results = array_merge($results, $r); - } - foreach ($results as $address) { - if (isset($address['__type']) && $address['__type'] == 'Object') { - $addresses[$address['__key']] = $address[$conf['addresses']['name_field']]; - } - } - } else { - $addresses = array(); - } - - $this->addVariable(_("Students"), 'students', 'multienum', false, false, null, array($addresses, 20)); - - $this->setButtons(array(_("Save"))); - } - - function execute() - { - global $conf, $prefs, $registry, $notification; - - /* Add new category. */ - if (strpos($this->_vars->get('category'), '*new*') !== false || $this->_vars->get('category') == $this->_vars->get('new_category')) { - $cManager = new Horde_Prefs_CategoryManager(); - $cManager->add($this->_vars->get('new_category')); - $this->_vars->set('category', $this->_vars->get('new_category')); - } - - $this->_class->set('name', $this->_vars->get('name')); - $this->_class->set('desc', $this->_vars->get('description')); - $this->_class->set('category', $this->_vars->get('category')); - $this->_class->set('address_book', $this->_vars->get('address_book')); - - require_once 'Horde/Date.php'; - foreach ($this->_schoolproperties as $property) { - if ($property == 'start' || $property == 'end') { - $date = new Horde_Date($this->_vars->get($property)); - $this->_vars->set($property, $date->datestamp()); - } else if ($property == 'marks' && $this->_vars->get($property . '_custom') != '') { - $this->_vars->set($property, $this->_vars->get($property . '_custom')); - } - $this->_class->set($property, $this->_vars->get($property) == '' ? null : $this->_vars->get($property)); - } - - // Save students - $driver = &Skoli_Driver::singleton($this->_vars->get('c')); - $result = $driver->addStudents($this->_vars->get('students')); - if (is_a($result, 'PEAR_Error')) { - $notification->push(_("Couldn't add the selected students to the class."), 'horde.warning'); - } - - $result = $this->_class->save(); - if (is_a($result, 'PEAR_Error')) { - return PEAR::raiseError(sprintf(_("Unable to save class \"%s\": %s"), $id, $result->getMessage())); - } - return true; - } - -} diff --git a/skoli/lib/Forms/Entry.php b/skoli/lib/Forms/Entry.php deleted file mode 100644 index d020ebfb3..000000000 --- a/skoli/lib/Forms/Entry.php +++ /dev/null @@ -1,184 +0,0 @@ - - * @package Skoli - */ -class Skoli_EntryForm extends Horde_Form { - - function Skoli_EntryForm(&$vars) - { - global $conf, $prefs, $registry; - - $update = $vars->exists('entry') && $vars->exists('view'); - - if ($vars->get('view') != 'Entry') { - parent::Horde_Form($vars, $update ? _("Update Entry") : _("Add Entry")); - } else { - parent::Horde_Form($vars); - } - - if ($update) { - $this->addHidden('', 'entry', 'text', true); - $this->addHidden('', 'view', 'text', true); - } - - $classes = Skoli::listClasses(false, Horde_Perms::EDIT); - $classes_enums = array(); - foreach ($classes as $class) { - if ($class->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT)) { - $classes_enums[$class->getName()] = $class->get('name'); - } - } - - if (!$this->_vars->exists('class_id') && $vars->exists('class')) { - $this->_vars->set('class_id', $vars->get('class')); - if (!$this->_vars->exists('student_id') && $vars->exists('student')) { - $this->_vars->set('student_id', array($vars->get('student'))); - } else { - $this->_vars->set('student_id', array()); - } - } - - // List classes - $actionvariable = &$this->addVariable(_("Class"), 'class_id', 'enum', true, count($classes)>1 ? false : true, null, array($classes_enums, _("Choose:"))); - if (count($classes) > 1) { - require_once 'Horde/Form/Action.php'; - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - } else { - reset($classes); - $this->addHidden('', 'class_id', 'text', true); - $this->_vars->set('class_id', key($classes)); - } - - // Load the selected students - if ($this->_vars->get('class_id') != '') { - $class = current(Skoli::listStudents($vars->get('class_id'))); - foreach ($class['_students'] as $address) { - $addresses[$address['student_id']] = $address[$conf['addresses']['name_field']]; - } - if ($update) { - $this->addVariable(_("Student"), 'student_id', 'enum', true, false, null, array($addresses)); - } else { - $this->addVariable(_("Student"), 'student_id', 'multienum', true, false, null, array($addresses, 14)); - } - } else { - $addresses = array(); - } - - $this->addVariable(_("Date"), 'object_time', 'monthdayyear', true, false, null, array(date('Y') - 10)); - if (!$this->_vars->exists('object_time')) { - $date = new Horde_Date(time()); - $this->_vars->set('object_time', array('month' => $date->month, 'day' => $date->mday, 'year' => $date->year)); - } - - // Load last type from preferences - if (!$this->_vars->exists('object_type')) { - $this->_vars->set('object_type', $prefs->getValue('default_objects_format')); - } - if ($conf['objects']['allow_marks']) { - $types['mark'] = _("Mark"); - } - if ($conf['objects']['allow_objectives']) { - $types['objective'] = _("Objective"); - } - if ($conf['objects']['allow_outcomes']) { - $types['outcome'] = _("Outcome"); - } - if ($conf['objects']['allow_absences']) { - $types['absence'] = _("Absence"); - } - $actionvariable = &$this->addVariable(_("Type"), 'object_type', 'radio', true, false, null, array($types)); - require_once 'Horde/Form/Action.php'; - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - - if ($this->_vars->get('object_type') != '' && $this->_vars->get('class_id') != '') { - switch ($this->_vars->get('object_type')) { - - case 'mark': - $this->addVariable(_("Title"), 'attribute_title', 'text', true, false); - switch ($class['marks']) { - case 'numbers': - $this->addVariable(_("Mark"), 'attribute_mark', 'number', true, false, _("Mark in numbers")); - break; - - case 'percent': - $this->addVariable(_("Mark"), 'attribute_mark', 'number', true, false, _("Mark in percent")); - break; - - default: - $marks_enums = preg_split('/\s*,\s*/', $class['marks']); - $this->addVariable(_("Mark"), 'attribute_mark', 'enum', true, false, null, array(array_combine($marks_enums, $marks_enums), _("Choose:"))); - } - // Load Skoli_School - require_once SKOLI_BASE . '/lib/School.php'; - $school = new Skoli_School($class['school']); - $school->addFormVariable($this, 'subject', array(true)); - $this->addVariable(_("Weight"), 'attribute_weight', 'number', true, false); - if (!$this->_vars->exists('attribute_weight')) { - $this->_vars->set('attribute_weight', 1); - } - break; - - case 'objective': - // Load Skoli_School - require_once SKOLI_BASE . '/lib/School.php'; - $school = new Skoli_School($class['school']); - $school->addFormVariable($this, 'subject', array(false, true)); - $school->addFormVariable($this, 'category', array($this->_vars->get('attribute_subject'))); - $this->addVariable(_("Objective"), 'attribute_objective', 'longtext', true, false, null, array(4, 60)); - break; - - case 'outcome': - $this->addVariable(_("Outcome"), 'attribute_outcome', 'longtext', true, false, null, array(2, 60)); - $this->addVariable(_("Completed?"), 'attribute_completed', 'boolean', true, false); - $this->addVariable(_("Comment"), 'attribute_comment', 'longtext', false, false, null, array(4, 60)); - break; - - case 'absence': - $this->addVariable(_("Absence"), 'attribute_absence', 'number', true, false, _("Absence in number of lessons")); - $this->addVariable(_("Excused?"), 'attribute_excused', 'boolean', true, false); - if (!$this->_vars->exists('attribute_absence')) { - $this->_vars->set('attribute_excused', true); - } - $this->addVariable(_("Comment"), 'attribute_comment', 'longtext', false, false, null, array(4, 60)); - break; - } - } - - $this->setButtons(array($update ? _("Save") : _("Add"))); - } - - function execute() - { - global $conf, $prefs, $registry, $notification; - - // Save last type to preferences - $prefs->setValue('default_objects_format', $this->_vars->get('object_type')); - - $driver = &Skoli_Driver::singleton($this->_vars->get('class_id')); - $result = $driver->addEntry($this->_vars); - if (is_a($result, 'PEAR_Error')) { - $notification->push(_("Couldn't add the new entry."), 'horde.warning'); - } - - return $result; - } -} diff --git a/skoli/lib/School.php b/skoli/lib/School.php deleted file mode 100644 index 7363f759c..000000000 --- a/skoli/lib/School.php +++ /dev/null @@ -1,287 +0,0 @@ - - * @package Skoli - */ -class Skoli_School { - - /** - * School list from template. - * - * @var array - */ - public static $schools; - - /** - * Current school from template. - * - * @var array - */ - var $school; - - /** - * Load the school list from template. - */ - function Skoli_School($schoolName) - { - self::_loadSchools(); - if (!isset(self::$schools[$schoolName]) || !is_array(self::$schools[$schoolName])) { - return PEAR::raiseError(sprintf(_("Error loading the school \"%s\" from template."), $schoolName)); - } else { - $this->school = self::$schools[$schoolName]; - } - } - - /** - * Adds a variable to the current form. - * - * @param Horde_Form $form The current form. - * - * @param string $property The property to add. - * - * @param array $params Property dependent parameters. - */ - function addFormVariable(&$form, $property, $params = array()) - { - switch ($property) { - case 'start': - case 'end': - $form->addVariable(_(ucfirst($property)), $property, 'monthdayyear', true, false, null, array(date('Y') - 10)); - if ($form->_vars->exists('semester') && isset($this->school['semester']) && is_array($this->school['semester'])) { - foreach ($this->school['semester'] as $semester) { - if ($semester['name'] == $form->_vars->get('semester')) { - $activesemester = $semester; - break; - } - } - $datevars = $form->_vars->get($property); - if (isset($activesemester[$property]) && empty($datevars['day'])) { - require_once 'Horde/Date.php'; - if ($property == 'start') { - $startdate = 0; - } else { - $startdate = new Horde_Date($form->_vars->get('start')); - $startdate = $startdate->datestamp(); - } - $date = new Horde_Date($this->_getSemesterTime($activesemester[$property], $startdate)); - $form->_vars->set($property, array('month' => $date->month, 'day' => $date->mday, 'year' => $date->year)); - } - } - break; - - case 'marks': - $marksformat = array( - 'numbers' => _("Format in numbers"), - 'percent' => _("Format in percent"), - 'custom' => _("Custom format:") - ); - if (isset($this->school[$property])) { - $form->_vars->set($property, $this->school[$property]); - if (!isset($marksformat[$this->school[$property]])) { - $marksformat['custom'] .= ' ' . $this->school[$property]; - $marksformat[$this->school[$property]] = $marksformat['custom']; - unset($marksformat['custom']); - } - $form->addVariable(_(ucfirst($property)), $property, 'enum', true, true, null, array($marksformat, _("Choose:"))); - } else { - require_once 'Horde/Form/Action.php'; - if ($form->_vars->exists($property) && !isset($marksformat[$form->_vars->get($property)])) { - $form->_vars->set($property . '_custom', $form->_vars->get($property)); - $form->_vars->set($property, 'custom'); - } - $actionvariable = &$form->addVariable(_(ucfirst($property)), $property, 'enum', true, false, null, array($marksformat, _("Choose:"))); - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - if ($form->_vars->get($property) == 'custom') { - $form->addVariable('', $property . '_custom', 'text', true, false, _("List with custom marks separated by comma (best mark first)")); - } - } - break; - - case 'subject': - $obligatory = isset($params[0]) ? $params[0] : true; - $onlywithobjectives = isset($params[1]) ? $params[1] : false; - if (isset($this->school['subjects'])) { - $values = array(); - foreach ($this->school['subjects'] as $key=>$value) { - if (!$onlywithobjectives || ($onlywithobjectives && is_array($value))) { - $subject = is_array($value) ? $key : $value; - $values[$subject] = $subject; - } - } - if ($onlywithobjectives) { - if (count($values) > 0) { - require_once 'Horde/Form/Action.php'; - $actionvariable = &$form->addVariable(_(ucfirst($property)), 'attribute_subject', 'enum', $obligatory, false, null, array(array_merge(array(_("Interdisciplinary")=>_("Interdisciplinary")), $values))); - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - } else { - $form->addVariable(_(ucfirst($property)), 'attribute_subject', 'text', true, true); - $form->_vars->set('attribute_subject', _("Interdisciplinary")); - } - } else { - $form->addVariable(_(ucfirst($property)), 'attribute_subject', 'enum', $obligatory, false, null, array($values, _("Choose:"))); - } - } else { - $form->addVariable(_(ucfirst($property)), 'attribute_subject', 'text', $obligatory, false); - } - break; - - case 'category': - $subject = !empty($params[0]) ? $params[0] : _("Interdisciplinary"); - if ($subject != _("Interdisciplinary") && isset($this->school['subjects'][$subject]) && is_array($this->school['subjects'][$subject])) { - $values = array(); - foreach ($this->school['subjects'][$subject] as $value) { - $values[$value] = $value; - } - $form->addVariable(_(ucfirst($property)), 'attribute_category', 'enum', true, false, null, array($values, _("Choose:"))); - } else if ($subject == _("Interdisciplinary") && isset($this->school['objectives'])) { - $values = array(); - foreach ($this->school['objectives'] as $value) { - $values[$value] = $value; - } - $form->addVariable(_(ucfirst($property)), 'attribute_category', 'enum', true, false, null, array($values, _("Choose:"))); - } else { - $form->addVariable(_(ucfirst($property)), 'attribute_category', 'text', true, false); - } - break; - - default: - if (isset($this->school[$property]) && is_array($this->school[$property])) { - if (count($this->school[$property]) > 1) { - $values = array(); - foreach ($this->school[$property] as $value) { - $key = is_array($value) ? $value['name'] : $value; - $values[$key] = $key; - } - if (is_array(current($this->school[$property]))) { - require_once 'Horde/Form/Action.php'; - $actionvariable = &$form->addVariable(_(ucfirst($property)), $property, 'enum', false, false, null, array($values, _("Choose:"))); - $actionvariable->setAction(Horde_Form_Action::factory('reload')); - } else { - $form->addVariable(_(ucfirst($property)), $property, 'enum', false, false, null, array($values, _("Choose:"))); - } - } else { - $form->addVariable(_(ucfirst($property)), $property, 'text', false, true); - $value = current($this->school[$property]); - $form->_vars->set($property, is_array($value) ? $value['name'] : $value); - } - } else { - $form->addVariable(_(ucfirst($property)), $property, 'text', false, false); - } - } - } - - /** - * Returns a timestamp for the specified semester start- or enddate. - * - * @param mixed The dateformat specified in conf/schools.php for this date. - * - * @return int The timestamp. - */ - private function _getSemesterTime($format, $startdate) - { - if (is_int($format)) { - // Timestamp format - $timestamp = $format; - } else if (preg_match('/^W([0-9]{2})\-[0-9]$/', $format, $m)) { - $year = date('Y'); - if (date('W') > $m[1]) { - $year++; - } - $timestamp = strtotime($year . '-' . $format); - } else { - $timestamp = strtotime($format); - } - if (is_int($timestamp) && $timestamp > 0) { - if ($startdate >= $timestamp) { - $timestamp = strtotime('+1 year', $timestamp); - } - return $timestamp; - } else { - return ''; - } - } - - /** - * Returns all schools specified in conf/schools.php. - * - * @return array The school list. - */ - public static function listSchools() - { - self::_loadSchools(); - $schools = array(); - foreach (self::$schools as $key=>$val) { - $schools[$key] = $val['title']; - } - return $schools; - } - - /** - * Loads the schools specified in conf/schools.php - */ - private static function _loadSchools() - { - if (!isset(self::$schools)) { - require_once SKOLI_BASE . '/config/schools.php'; - self::$schools = $cfgSchools; - } - } - - /** - * Returns all addressbooks skoli is defined to use. - * - * @param boolean $all If set to true return all addressbooks a user has access to. - * - * @return array The address book list. - */ - public static function listAddressBooks($all = false) - { - global $conf, $prefs, $registry; - - $addressbooks = $registry->call('contacts/sources'); - - if (!$all && $conf['addresses']['storage'] == 'custom') { - if (isset($addressbooks[$conf['addresses']['address_book']])) { - $addressbooks = array($conf['addresses']['address_book'] => $addressbooks[$conf['addresses']['address_book']]); - } else { - $addressbooks = array(); - } - } - - return $addressbooks; - } - - /** - * Returns the parsed contact list name. - * - * @param string $contactlist The contact list name to parse. - * - * @param Horde_Variables $vars The variables to use as replacement. - * - * @param boolean $force If set to true also replaces empty fields. - * - * @return string The parsed contact list name. - */ - public static function parseContactListName($contactlist, $vars, $force = false) - { - $contactlistsubs = array( - '%c' => 'name', - '%g' => 'grade', - '%s' => 'semester' - ); - foreach ($contactlistsubs as $pattern=>$field) { - if (strpos($contactlist, $pattern) !== false && ($vars->get($field) != '' || $force)) { - $contactlist = str_replace($pattern, $vars->get($field), $contactlist); - } - } - return $contactlist; - } - -} diff --git a/skoli/lib/Skoli.php b/skoli/lib/Skoli.php deleted file mode 100644 index 2a6efe281..000000000 --- a/skoli/lib/Skoli.php +++ /dev/null @@ -1,1076 +0,0 @@ - - * @package Skoli - */ -class Skoli { - - /** - * Initial app setup code. - */ - function initialize() - { - // Update the preference for what classes to display. If the user - // doesn't have any selected class then do nothing. - $GLOBALS['display_classes'] = @unserialize($GLOBALS['prefs']->getValue('display_classes')); - if (!$GLOBALS['display_classes']) { - $GLOBALS['display_classes'] = array(); - } - if (($classId = Horde_Util::getFormData('display_class')) !== null) { - if (is_array($classId)) { - $GLOBALS['display_classes'] = $classId; - } else { - if (in_array($classId, $GLOBALS['display_classes'])) { - $key = array_search($classId, $GLOBALS['display_classes']); - unset($GLOBALS['display_classes'][$key]); - } else { - $GLOBALS['display_classes'][] = $classId; - } - } - $GLOBALS['prefs']->setValue('show_students', Horde_Util::getFormData('show_students') ? 1 : 0); - } - - $GLOBALS['prefs']->setValue('display_classes', serialize($GLOBALS['display_classes'])); - } - - /** - * Returns all classes a user has access to, according to several - * parameters/permission levels. - * - * @param boolean $owneronly Only return classes that this user owns? - * Defaults to false. - * @param integer $permission The permission to filter classes by. - * - * @return array The class list. - */ - function listClasses($owneronly = false, $permission = Horde_Perms::SHOW) - { - if ($owneronly && !$GLOBALS['registry']->getAuth()) { - return array(); - } - - $classes = $GLOBALS['skoli_shares']->listShares($GLOBALS['registry']->getAuth(), $permission, $owneronly ? $GLOBALS['registry']->getAuth() : null, 0, 0, 'name'); - if (is_a($classes, 'PEAR_Error')) { - Horde::logMessage($classes, 'ERR'); - return array(); - } - - // Check if we have access to the attached addressbook. - $addressbooks = $GLOBALS['registry']->call('contacts/sources'); - foreach ($classes as $key=>$val) { - if (!isset($addressbooks[$val->get('address_book')])) { - unset($classes[$key]); - } - } - - return $classes; - } - - /** - * Retrieves the current user's student list from storage. - * - * This function will also sort the resulting list, if requested. - * - * @param array $classes An array of classes to display, a - * single classname or null/empty to - * display classes $GLOBALS['display_classes']. - * @param string $sortby_student The field by which to sort - * (SKOLI_SORT_PRIORITY, SKOLI_SORT_NAME - * SKOLI_SORT_DUE, SKOLI_SORT_COMPLETION). - * @param integer $sortdir_student The direction by which to sort - * (SKOLI_SORT_ASCEND, SKOLI_SORT_DESCEND). - * @param string $sortby_class The field by which to sort - * (SKOLI_SORT_PRIORITY, SKOLI_SORT_NAME - * SKOLI_SORT_DUE, SKOLI_SORT_COMPLETION). - * @param integer $sortdir_class The direction by which to sort - * (SKOLI_SORT_ASCEND, SKOLI_SORT_DESCEND). - * - * @return array A list of the requested classes with students. - */ - function listStudents($classes = null, - $sortby_student = null, - $sortdir_student = null, - $sortby_class = null, - $sortdir_class = null) - { - global $prefs, $registry; - - if (is_null($classes)) { - $classes = $GLOBALS['display_classes']; - } else if (!is_array($classes)) { - $classes = array($classes); - } - if (is_null($sortby_student)) { - $sortby_student = $prefs->getValue('sortby_student'); - } - if (is_null($sortdir_student)) { - $sortdir_student = $prefs->getValue('sortdir_student'); - } - if (is_null($sortby_class)) { - $sortby_class = $prefs->getValue('sortby_class'); - } - if (is_null($sortdir_class)) { - $sortdir_class = $prefs->getValue('sortdir_class'); - } - - $list = array(); - $i = 0; - $addressbooks = $registry->call('contacts/sources'); - foreach ($classes as $class) { - /* Get all data about the shared class */ - $share = $GLOBALS['skoli_shares']->getShare($class); - - /* Check permissions */ - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ) || !isset($addressbooks[$share->get('address_book')])) { - continue; - } - - $list[$i] = $share->datatreeObject->data; - $list[$i]['_id'] = $class; - $list[$i]['_edit'] = $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT); - - /* Add all students to the list */ - $driver = &Skoli_Driver::singleton($class); - $list[$i]['_students'] = $driver->getStudents(); - $student_columns = @unserialize($prefs->getValue('student_columns')); - foreach ($list[$i]['_students'] as $key=>$student) { - $studentdetails = Skoli::getStudent($list[$i]['address_book'], $student['student_id']); - if (count($studentdetails) > 0) { - $list[$i]['_students'][$key] += $studentdetails; - if (in_array('lastentry', $student_columns)) { - $list[$i]['_students'][$key]['_lastentry'] = $driver->lastEntry($student['student_id']); - } - if (in_array('summarks', $student_columns)) { - $list[$i]['_students'][$key]['_summarks'] = Skoli::sumMarks($class, $student['student_id']); - } - if (in_array('sumabsences', $student_columns)) { - $list[$i]['_students'][$key]['_sumabsences'] = Skoli::sumAbsences($class, $student['student_id']); - } - } else { - unset($list[$i]['_students'][$key]); - } - } - $i++; - } - - /* Sort the array if we have a sort function defined for this - * field. */ - $prefix = ($sortdir_class == SKOLI_SORT_DESCEND) ? '_rsort' : '_sort'; - usort($list, array('Skoli', $prefix . '_class_' . $sortby_class)); - $prefix = ($sortdir_student == SKOLI_SORT_DESCEND) ? '_rsort' : '_sort'; - for ($i = 0; $i < count($list); $i++) { - usort($list[$i]['_students'], array('Skoli', $prefix . '_student_' . $sortby_student)); - } - - return $list; - } - - /** - * Retrieves all data about a student. - * - * @param string $addressbook The addressbook. - * - * @param string $id An ID from the student contact. - * - * @return array A list with the data from the requested student. - */ - function getStudent($addressbook, $id) - { - global $registry; - - $student = array(); - $apiargs = array( - 'source' => $addressbook, - 'objectId' => $id - ); - try { - $student = $registry->call('contacts/getContact', $apiargs); - } catch (Horde_Exception $e) { - $notification->push(sprintf(_("Couldn't create the contact list \"%s\"."), $this->_vars->get('contact_list')), 'horde.info'); - } - return $student; - } - - /** - * Retrieves a sorted entry list from storage. - * - * @param string $classid The class ID. - * - * @param string $studentid The student ID. - * - * @param string $type The entry type to search in. - * - * @param array $searchparams Some additional search parameters. - * - * @param string $sortby The field by which to sort - * (SKOLI_SORT_CLASS, SKOLI_SORT_STUDENT - * SKOLI_SORT_DATE, SKOLI_SORT_TYPE). - * @param integer $sortdir The direction by which to sort - * (SKOLI_SORT_ASCEND, SKOLI_SORT_DESCEND). - * - * @return array Sorted list with all entries. - */ - function listEntries($classid = null, - $studentid = null, - $type = null, - $searchparams = array(), - $sortby = null, - $sortdir = null) - { - global $conf, $prefs, $registry; - - $dateFormat = $prefs->getValue('date_format'); - $entryTypes = array( - 'mark' => _("Mark"), - 'objective' => _("Objective"), - 'outcome' => _("Outcome"), - 'absence' => _("Absence") - ); - - if (is_null($classid)) { - $classes = Skoli::listClasses(); - } else { - $share = $GLOBALS['skoli_shares']->getShare($classid); - $classes = array($classid => $share); - } - - if (is_null($sortby)) { - $sortby = SKOLI_SORT_CLASS; - } - if (is_null($sortdir)) { - $sortdir = SKOLI_SORT_ASCEND; - } - - $entrylist = array(); - $i = 0; - $addressbooks = $registry->call('contacts/sources'); - foreach ($classes as $class_id=>$share) { - /* Check permissions */ - if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ) || !isset($addressbooks[$share->get('address_book')])) { - continue; - } - - $share_permissions_edit = $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT); - $share_permissions_delete = $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::DELETE); - - $driver = &Skoli_Driver::singleton($class_id); - $entries = $driver->getEntries($studentid, $type, $searchparams); - foreach ($entries as $student) { - $studentdetails = Skoli::getStudent($share->get('address_book'), $student['student_id']); - foreach ($student['_entries'] as $entry) { - $entrylist[$i] = $entry['_attributes']; - $entrylist[$i]['class'] = $share->get('name'); - $entrylist[$i]['classid'] = $class_id; - $entrylist[$i]['student'] = $studentdetails[$conf['addresses']['name_field']]; - $entrylist[$i]['date'] = strftime($dateFormat, $entry['object_time']); - $entrylist[$i]['timestamp'] = $entry['object_time']; - $entrylist[$i]['typename'] = $entryTypes[$entry['object_type']]; - $entrylist[$i]['type'] = $entry['object_type']; - $entrylist[$i]['_edit'] = $share_permissions_edit; - $entrylist[$i]['_delete'] = $share_permissions_delete; - $entrylist[$i]['_id'] = $entry['object_id']; - $i++; - } - } - } - - /* Sort the array if we have a sort function defined for this - * field. */ - $prefix = ($sortdir == SKOLI_SORT_DESCEND) ? '_rsort' : '_sort'; - usort($entrylist, array('Skoli', $prefix . '_entry_' . $sortby)); - - return $entrylist; - } - - /** - * Sum up all excused and not excused absences for a given student. - * - * @param string $classid An ID from the class. - * - * @param string $studentid An ID from the student contact. - * - * @return array A list with the requested data. - */ - function sumAbsences($classid, $studentid) - { - $driver = &Skoli_Driver::singleton($classid); - $entries = current($driver->getEntries($studentid, 'absence')); - - $excused = 0; - $notexcused = 0; - foreach($entries['_entries'] as $entry) { - $entry['_attributes']['absence'] = Skoli::convertNumber($entry['_attributes']['absence']); - if (empty($entry['_attributes']['excused'])) { - $notexcused += $entry['_attributes']['absence']; - } else { - $excused += $entry['_attributes']['absence']; - } - } - - return array($excused, $notexcused, $excused + $notexcused); - } - - /** - * Sum up all completed and open outcomes for a given student. - * - * @param string $classid An ID from the class. - * - * @param string $studentid An ID from the student contact. - * - * @return array A list with the requested data. - */ - function sumOutcomes($classid, $studentid) - { - $driver = &Skoli_Driver::singleton($classid); - $entries = current($driver->getEntries($studentid, 'outcome')); - - $completed = 0; - $open = 0; - foreach($entries['_entries'] as $entry) { - if (empty($entry['_attributes']['completed'])) { - $open++; - } else { - $completed++; - } - } - - return array($completed, $open, $completed + $open); - } - - /** - * Sum up all marks for a given student. - * - * @param string $classid An ID from the class. - * - * @param string $studentid An ID from the student contact. - * - * @param string $subject Only sum up marks from this subject. - * - * @return float The requested data. - */ - function sumMarks($classid, $studentid, $subject = null) - { - global $prefs; - - $driver = &Skoli_Driver::singleton($classid); - if (!is_null($subject)) { - $params = array(array('name' => 'subject', 'value' => $subject, 'strict' => 1)); - } else { - $params = null; - } - $entries = current($driver->getEntries($studentid, 'mark', $params)); - - /* Count weights */ - $totalweight = 0; - foreach($entries['_entries'] as $entry) { - $totalweight += Skoli::convertNumber($entry['_attributes']['weight']); - } - - if ($totalweight <= 0) { - return ''; - } - - $sum = 0; - $weight = 100 / $totalweight; - foreach($entries['_entries'] as $entry) { - $sum += $weight * Skoli::convertNumber($entry['_attributes']['weight']) * Skoli::convertNumber($entry['_attributes']['mark']); - } - - if ($sum > 0) { - return round($sum / 100, $prefs->getValue('marks_roundby')); - } else { - return ''; - } - } - - /** - * Converts numbers with a comma to a valid php number. - * - * @param string $number The number to convert. - * - * @return string The converted number - */ - function convertNumber($number) - { - $number = str_replace(',', '.', $number); - return $number; - } - - /** - * Build Skoli's list of menu items. - */ - function getMenu() - { - global $conf, $registry, $browser, $print_link; - - $menu = new Horde_Menu(Horde_Menu::MASK_ALL); - $menu->add(Horde::url('list.php'), _("List Classes"), 'skoli.png', null, null, null, basename($_SERVER['PHP_SELF']) == 'index.php' ? 'current' : null); - if (count(Skoli::listClasses(false, Horde_Perms::EDIT))) { - $menu->add(Horde::url('add.php'), _("_New Entry"), 'add.png', null, null, null, Horde_Util::getFormData('entry') ? '__noselection' : null); - } - - /* Search. */ - $menu->add(Horde::url('search.php'), _("_Search"), 'search.png', Horde_Themes::img(null, 'horde')); - - /* Import/Export. */ - if ($conf['menu']['export']) { - $menu->add(Horde::url('data.php'), _("_Export"), 'data.png', Horde_Themes::img(null, 'horde')); - } - - // @TODO Implement an easy form to create timetables in e.g. Kronolith - /* Timetable. - * Show this item only if an application provides 'calendar/show' and we have permissions to view it. - $app = $registry->hasMethod('calendar/show'); - if ($app !== false && $registry->get('status', $app) != 'inactive' && $registry->hasPermission($app, Horde_Perms::EDIT)) { - $menu->add(Horde::url(Horde_Util::addParameter('timetable.php', 'actionID', 'new_timetable')), _("_New Timetable"), 'timetable.png'); - } - */ - - return $menu; - } - - /** - * Comparison function for sorting classes by semester start date. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer 1 if class one is greater, -1 if class two is greater; - * 0 if they are equal. - */ - function _sort_class_semesterstart($a, $b) - { - if ($a['start'] == $b['start'] ) { - return 0; - } - - // Treat empty start dates as farthest into the future. - if ($a['start'] == 0) { - return 1; - } - if ($b['start'] == 0) { - return -1; - } - - return ($a['start'] > $b['start']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting classes by semester start date. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer -1 if class one is greater, 1 if class two is greater, - * 0 if they are equal. - */ - function _rsort_class_semesterstart($a, $b) - { - if ($a['start'] == $b['start']) { - return 0; - } - - // Treat empty start dates as farthest into the future. - if ($a['start'] == 0) { - return -1; - } - if ($b['start'] == 0) { - return 1; - } - - return ($a['start'] < $b['start']) ? 1 : -1; - } - - /** - * Comparison function for sorting classes by semester end date. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer 1 if class one is greater, -1 if class two is greater; - * 0 if they are equal. - */ - function _sort_class_semesterend($a, $b) - { - if ($a['end'] == $b['end'] ) { - return 0; - } - - // Treat empty end dates as farthest into the future. - if ($a['end'] == 0) { - return 1; - } - if ($b['end'] == 0) { - return -1; - } - - return ($a['end'] > $b['end']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting classes by semester end date. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer -1 if class one is greater, 1 if class two is greater, - * 0 if they are equal. - */ - function _rsort_class_semesterend($a, $b) - { - if ($a['end'] == $b['end']) { - return 0; - } - - // Treat empty end dates as farthest into the future. - if ($a['end'] == 0) { - return -1; - } - if ($b['end'] == 0) { - return 1; - } - - return ($a['end'] < $b['end']) ? 1 : -1; - } - - /** - * Comparison function for sorting classes by name. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer 1 if class one is greater, -1 if class two is greater; - * 0 if they are equal. - */ - function _sort_class_name($a, $b) - { - return strcasecmp($a['name'], $b['name']); - } - - /** - * Comparison function for reverse sorting classes by name. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer -1 if class one is greater, 1 if class two is greater; - * 0 if they are equal. - */ - function _rsort_class_name($a, $b) - { - return strcasecmp($b['name'], $a['name']); - } - - /** - * Comparison function for sorting classes by grade. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer 1 if class one is greater, -1 if class two is greater; - * 0 if they are equal. - */ - function _sort_class_grade($a, $b) - { - return strcasecmp($a['grade'], $b['grade']); - } - - /** - * Comparison function for reverse sorting classes by grade. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer -1 if class one is greater, 1 if class two is greater; - * 0 if they are equal. - */ - function _rsort_class_grade($a, $b) - { - return strcasecmp($b['grade'], $a['grade']); - } - - /** - * Comparison function for sorting classes by semester. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer 1 if class one is greater, -1 if class two is greater; - * 0 if they are equal. - */ - function _sort_class_semester($a, $b) - { - return strcasecmp($a['semester'], $b['semester']); - } - - /** - * Comparison function for reverse sorting classes by semester. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer -1 if class one is greater, 1 if class two is greater; - * 0 if they are equal. - */ - function _rsort_class_semester($a, $b) - { - return strcasecmp($b['semester'], $a['semester']); - } - - /** - * Comparison function for sorting classes by location. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer 1 if class one is greater, -1 if class two is greater; - * 0 if they are equal. - */ - function _sort_class_location($a, $b) - { - return strcasecmp($a['location'], $b['location']); - } - - /** - * Comparison function for reverse sorting classes by location. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer -1 if class one is greater, 1 if class two is greater; - * 0 if they are equal. - */ - function _rsort_class_location($a, $b) - { - return strcasecmp($b['location'], $a['location']); - } - - /** - * Comparison function for sorting classes by category. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer 1 if class one is greater, -1 if class two is greater; - * 0 if they are equal. - */ - function _sort_class_category($a, $b) - { - return strcasecmp($a['category'] ? $a['category'] : _("Unfiled"), - $b['category'] ? $b['category'] : _("Unfiled")); - } - - /** - * Comparison function for reverse sorting classes by category. - * - * @param array $a Class one. - * @param array $b Class two. - * - * @return integer -1 if class one is greater, 1 if class two is greater; - * 0 if they are equal. - */ - function _rsort_class_category($a, $b) - { - return strcasecmp($b['category'] ? $b['category'] : _("Unfiled"), - $a['category'] ? $a['category'] : _("Unfiled")); - } - - /** - * Comparison function for sorting students by name. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer 1 if student one is greater, -1 if student two is greater; - * 0 if they are equal. - */ - function _sort_student_name($a, $b) - { - return strcasecmp($a['name'], $b['name']); - } - - /** - * Comparison function for reverse sorting students by name. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer -1 if student one is greater, 1 if student two is greater; - * 0 if they are equal. - */ - function _rsort_student_name($a, $b) - { - return strcasecmp($b['name'], $a['name']); - } - - /** - * Comparison function for sorting students by last entry date. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer 1 if student one is greater, -1 if student two is greater; - * 0 if they are equal. - */ - function _sort_student_lastentry($a, $b) - { - // Treat empty dates as farthest into the past. - if (!isset($a['_lastentry']) || $a['_lastentry'] == 0) { - return -1; - } - if (!isset($b['_lastentry']) || $b['_lastentry'] == 0) { - return 1; - } - - if ($a['_lastentry'] == $b['_lastentry'] ) { - return 0; - } - - return ($a['_lastentry'] > $b['_lastentry']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting students by last entry date. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer -1 if student one is greater, 1 if student two is greater, - * 0 if they are equal. - */ - function _rsort_student_lastentry($a, $b) - { - // Treat empty dates as farthest into the past. - if (!isset($a['_lastentry']) || $a['_lastentry'] == 0) { - return 1; - } - if (!isset($b['_lastentry']) || $b['_lastentry'] == 0) { - return -1; - } - - if ($a['_lastentry'] == $b['_lastentry']) { - return 0; - } - - return ($a['_lastentry'] < $b['_lastentry']) ? 1 : -1; - } - - /** - * Comparison function for sorting students by sumabsences. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer 1 if student one is greater, -1 if student two is greater; - * 0 if they are equal. - */ - function _sort_student_sumabsences($a, $b) - { - if ($a['_sumabsences'] == $b['_sumabsences'] ) { - return 0; - } - - return ($a['_sumabsences'] > $b['_sumabsences']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting students by sumabsences. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer -1 if student one is greater, 1 if student two is greater, - * 0 if they are equal. - */ - function _rsort_student_sumabsences($a, $b) - { - if ($a['_sumabsences'] == $b['_sumabsences']) { - return 0; - } - - return ($a['_sumabsences'] < $b['_sumabsences']) ? 1 : -1; - } - - /** - * Comparison function for sorting students by summarks. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer 1 if student one is greater, -1 if student two is greater; - * 0 if they are equal. - */ - function _sort_student_summarks($a, $b) - { - // Treat empty sums as lowest mark. - if ($a['_summarks'] == '') { - return -1; - } - if ($b['_summarks'] == '') { - return 1; - } - - if ($a['_summarks'] == $b['_summarks'] ) { - return 0; - } - - return ($a['_summarks'] > $b['_summarks']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting students by summarks. - * - * @param array $a Student one. - * @param array $b Student two. - * - * @return integer -1 if student one is greater, 1 if student two is greater, - * 0 if they are equal. - */ - function _rsort_student_summarks($a, $b) - { - // Treat empty sums as lowest mark. - if ($a['_summarks'] == '') { - return 1; - } - if ($b['_summarks'] == '') { - return -1; - } - - if ($a['_summarks'] == $b['_summarks']) { - return 0; - } - - return ($a['_summarks'] < $b['_summarks']) ? 1 : -1; - } - - /** - * Comparison function for sorting entries by date. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer 1 if entry one is greater, -1 if entry two is greater; - * 0 if they are equal. - */ - function _sort_entry_date($a, $b) - { - if ($a['timestamp'] == $b['timestamp'] ) { - return 0; - } - - return ($a['timestamp'] > $b['timestamp']) ? -1 : 1; - } - - /** - * Comparison function for reverse sorting entries by date. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer -1 if entry one is greater, 1 if entry two is greater, - * 0 if they are equal. - */ - function _rsort_entry_date($a, $b) - { - if ($a['timestamp'] == $b['timestamp']) { - return 0; - } - - return ($a['timestamp'] < $b['timestamp']) ? -1 : 1; - } - - /** - * Comparison function for sorting entries by class. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer 1 if entry one is greater, -1 if entry two is greater; - * 0 if they are equal. - */ - function _sort_entry_class($a, $b) - { - if ($a['class'] == $b['class'] ) { - return Skoli::_sort_entry_date($a, $b); - } - - return ($a['class'] > $b['class']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting entries by class. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer -1 if entry one is greater, 1 if entry two is greater, - * 0 if they are equal. - */ - function _rsort_entry_class($a, $b) - { - if ($a['class'] == $b['class']) { - return Skoli::_rsort_entry_date($a, $b); - } - - return ($a['class'] < $b['class']) ? 1 : -1; - } - - /** - * Comparison function for sorting entries by student. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer 1 if entry one is greater, -1 if entry two is greater; - * 0 if they are equal. - */ - function _sort_entry_student($a, $b) - { - if ($a['student'] == $b['student'] ) { - return Skoli::_sort_entry_date($a, $b); - } - - return ($a['student'] > $b['student']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting entries by student. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer -1 if entry one is greater, 1 if entry two is greater, - * 0 if they are equal. - */ - function _rsort_entry_student($a, $b) - { - if ($a['student'] == $b['student']) { - return Skoli::_rsort_entry_date($a, $b); - } - - return ($a['student'] < $b['student']) ? 1 : -1; - } - - /** - * Comparison function for sorting entries by type. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer 1 if entry one is greater, -1 if entry two is greater; - * 0 if they are equal. - */ - function _sort_entry_type($a, $b) - { - if ($a['type'] == $b['type'] ) { - return Skoli::_sort_entry_date($a, $b); - } - - return ($a['type'] > $b['type']) ? 1 : -1; - } - - /** - * Comparison function for reverse sorting entries by type. - * - * @param array $a Entry one. - * @param array $b Entry two. - * - * @return integer -1 if entry one is greater, 1 if entry two is greater, - * 0 if they are equal. - */ - function _rsort_entry_type($a, $b) - { - if ($a['type'] == $b['type']) { - return Skoli::_rsort_entry_date($a, $b); - } - - return ($a['type'] < $b['type']) ? 1 : -1; - } -} diff --git a/skoli/lib/base.php b/skoli/lib/base.php deleted file mode 100644 index 0674dae46..000000000 --- a/skoli/lib/base.php +++ /dev/null @@ -1,37 +0,0 @@ -pushApp('skoli', array('check_perms' => (Horde_Util::nonInputVar('skoli_authentication') != 'none'), 'logintasks' => true)); -} catch (Horde_Exception $e) { - $registry->authenticateFailure('skoli', $e); -} -$conf = &$GLOBALS['conf']; -@define('SKOLI_TEMPLATES', $registry->get('templates')); - -// Define the base file path of Skoli. -@define('SKOLI_BASE', dirname(__FILE__) . '/..'); - -// Start output compression. -Horde::compressOutput(); - -// Create a share instance. -$GLOBALS['skoli_shares'] = $GLOBALS['injector']->getInstance('Horde_Share_Factory')->getScope(); - -Skoli::initialize(); diff --git a/skoli/list.php b/skoli/list.php deleted file mode 100644 index 24d431471..000000000 --- a/skoli/list.php +++ /dev/null @@ -1,159 +0,0 @@ - - */ - -@define('SKOLI_BASE', dirname(__FILE__)); -require_once SKOLI_BASE . '/lib/base.php'; - -$title = _("My Classes"); - -/* Get and set Variables */ -$vars = Horde_Variables::getDefaultVariables(); - -/* Get the current action ID. */ -$actionID = Horde_Util::getFormData('actionID'); - -/* Sort out the sorting values */ -if (($sortby_class = Horde_Util::getFormData('sortby_class')) !== null) { - if ($sortby_class == $prefs->getValue('sortby_class')) { - $prefs->setValue('sortdir_class', !$prefs->getValue('sortdir_class')); - } else { - $prefs->setValue('sortdir_class', SKOLI_SORT_ASCEND); - } - $prefs->setValue('sortby_class', $sortby_class); - if ($sortby_class == 'name') { - if ($sortby_class == $prefs->getValue('sortby_student')) { - $prefs->setValue('sortdir_student', !$prefs->getValue('sortdir_student')); - } else { - $prefs->setValue('sortdir_student', SKOLI_SORT_ASCEND); - } - $prefs->setValue('sortby_student', $sortby_class); - } -} -if (($sortby_student = Horde_Util::getFormData('sortby_student')) !== null) { - $prefs->setValue('sortby_student', $sortby_student); - if ($sortby_student == $prefs->getValue('sortby_student')) { - $prefs->setValue('sortdir_student', !$prefs->getValue('sortdir_student')); - } else { - $prefs->setValue('sortdir_student', SKOLI_SORT_ASCEND); - } -} - -/* Check if we have access to an application who provides contacts/getContact */ -$app = $registry->hasMethod('contacts/getContact'); -if ($app == false || $registry->get('status', $app) == 'inactive' || !$registry->hasPermission($app, Horde_Perms::SHOW)) { - $notification->push(_("Skoli needs an applications who provides contacts (e.g. turba)."), 'horde.warning'); -} - -/* Redirect to create a new class if we don't have access to any class */ -if (count(Skoli::listClasses()) == 0 && $GLOBALS['registry']->getAuth()) { - $notification->push(_("Please create a new Class first."), 'horde.message'); - Horde::url('classes/create.php', true)->redirect(); -} - -switch ($actionID) { -case 'search_classes': - /* Get the search parameters. */ - $search_pattern = Horde_Util::getFormData('search_pattern'); - - /* Get the full, sorted student list for all classes. */ - $list = Skoli::listStudents(null, - $prefs->getValue('sortby_student'), - $prefs->getValue('sortdir_student'), - $prefs->getValue('sortby_class'), - $prefs->getValue('sortdir_class')); - - if (!empty($search_pattern)) { - $pattern = '/' . preg_quote($search_pattern, '/') . '/i'; - $search_results = array(); - foreach ($list as $class) { - $search_results_students = array(); - if (($search_name && preg_match($pattern, $task->name)) || - ($search_desc && preg_match($pattern, $task->desc)) || - ($search_category && preg_match($pattern, $task->category))) { - $search_results->add($task); - } - } - - /* Reassign $list to the search result. */ - $list = $search_results; - $title = sprintf(_("Search: Results for \"%s\""), $search_pattern); - } - break; - -default: - /* Get the full, sorted list for all classes. */ - $list = Skoli::listStudents(null, - $prefs->getValue('sortby_student'), - $prefs->getValue('sortdir_student'), - $prefs->getValue('sortby_class'), - $prefs->getValue('sortdir_class')); - break; -} - -Horde::addScriptFile('tooltips.js', 'horde'); -Horde::addScriptFile('effects.js', 'horde'); -Horde::addScriptFile('quickfinder.js', 'horde'); - -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -echo '
    '; -require SKOLI_TEMPLATES . '/list/header.inc'; - -if (count($list) > 0) { - $sortby_class = $prefs->getValue('sortby_class'); - $sortdir_class = $prefs->getValue('sortdir_class'); - $sortby_student = $prefs->getValue('sortby_student'); - $sortdir_student = $prefs->getValue('sortdir_student'); - $dateFormat = $prefs->getValue('date_format'); - $class_columns = @unserialize($prefs->getValue('class_columns')); - $show_students = $prefs->getValue('show_students'); - $student_columns = $show_students ? @unserialize($prefs->getValue('student_columns')) : array(); - $dynamic_sort = true; - - $baseurl = 'list.php'; - if ($actionID == 'search_classes') { - $baseurl = Horde_Util::addParameter( - $baseurl, - array('actionID' => 'search_classes', - 'search_pattern' => $search_pattern)); - } - - require SKOLI_TEMPLATES . '/list/headers.inc'; - - foreach ($list as $class) { - $dynamic_sort &= !$show_students; - $style = 'linedRow'; - require SKOLI_TEMPLATES . '/list/classes.inc'; - - if ($show_students) { - $treedir = Horde_Themes::img(null, 'horde'); - $counter = 0; - foreach ($class['_students'] as $student) { - if (++$counter < count($class['_students'])) { - $treeIcon = Horde::img(empty($GLOBALS['registry']->nlsconfig['rtl'][$GLOBALS['language']]) ? 'tree/join.png' : 'tree/rev-join.png', '+', '', $treedir); - } else { - $treeIcon = Horde::img(empty($GLOBALS['registry']->nlsconfig['rtl'][$GLOBALS['language']]) ? 'tree/joinbottom.png' : 'tree/rev-joinbottom.png', '\\', '', $treedir); - } - require SKOLI_TEMPLATES . '/list/students.inc'; - } - } - } - - require SKOLI_TEMPLATES . '/list/footers.inc'; - - if ($dynamic_sort) { - Horde::addScriptFile('tables.js', 'horde'); - } -} else { - require SKOLI_TEMPLATES . '/list/empty.inc'; -} - -require SKOLI_TEMPLATES . '/panel.inc'; -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/locale/.htaccess b/skoli/locale/.htaccess deleted file mode 100644 index 3a4288278..000000000 --- a/skoli/locale/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/skoli/locale/de/LC_MESSAGES/skoli.mo b/skoli/locale/de/LC_MESSAGES/skoli.mo deleted file mode 100644 index de30bf01ed6cf75f6422d3f7996c11d4a1f9da50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172277 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 N6-}F#fa=$p{}016k=pNOTE: You can use %c, %g or " -"%s as substitution for the class, grade respectively semester name." -msgstr "" -"Eingabe eines Standardnamens für neue Kontaktlisten.
    HINWEIS: Sie " -"können %c, %g oder %s als Ersatz für die Klasse (class), Stufe (grade) und " -"Semester (semester) verwenden." - -#: config/prefs.php.dist:165 -msgid "" -"Enter some custom marks and separate them by comma (best mark first).
    NOTE: You also need to choose \"Custom settings\" above." -msgstr "" -"Eingabe eines eigenen Notenformats. Jede Note wird mit einem Komma getrennt " -"(beste Note zuerst).
    HINWEIS: Sie müssen auch den Punkt \"Eigene " -"Einstellungen\" weiter oben auswählen." - -#: templates/search/headers.inc:46 -msgid "Entry" -msgstr "Eintrag" - -#: entry.php:100 -#, php-format -msgid "Entry for \"%s\"" -msgstr "Eintrag für \"%s\"" - -#: entry.php:23 -msgid "Entry not found." -msgstr "Eintrag nicht gefunden." - -#: lib/School.php:36 -#, php-format -msgid "Error loading the school \"%s\" from template." -msgstr "Fehler beim Laden der Schule \"%s\" aus der Vorlage." - -#: data.php:133 search.php:167 -msgid "Excused" -msgstr "Entschuldigt" - -#: data.php:68 -msgid "Excused absences" -msgstr "Entschuldigte Abwesenheiten" - -#: lib/Forms/Entry.php:157 -msgid "Excused?" -msgstr "Entschuldigt?" - -#: config/schools.php.dist:111 -msgid "Exercise processing" -msgstr "Aufgabenbearbeitung" - -#: templates/data/export.inc:32 -msgid "Export" -msgstr "Exportieren" - -#: data.php:171 templates/data/export.inc:5 -msgid "Export Classes" -msgstr "Klassen exportieren" - -#: data.php:63 -msgid "Firstname" -msgstr "Vorname" - -#: lib/School.php:81 -msgid "Format in numbers" -msgstr "Format in Zahlen" - -#: lib/School.php:82 -msgid "Format in percent" -msgstr "Format in Prozent" - -#: config/schools.php.dist:95 -msgid "French" -msgstr "Französisch" - -#: config/prefs.php.dist:7 config/prefs.php.dist:14 config/prefs.php.dist:21 -msgid "General Options" -msgstr "Allgemeine Einstellungen" - -#: lib/Forms/EditClass.php:56 lib/Forms/CreateClass.php:55 -msgid "General Settings" -msgstr "Allgemeine Angaben" - -#: config/schools.php.dist:80 -msgid "German" -msgstr "Deutsch" - -#: templates/list/headers.inc:72 config/prefs.php.dist:50 -#: config/prefs.php.dist:66 -msgid "Grade" -msgstr "Stufe" - -#: config/schools.php.dist:96 config/schools.php.dist:102 -msgid "Hearing" -msgstr "Hörverstehen" - -#: config/schools.php.dist:81 -msgid "Hearing and Talking" -msgstr "Hören und Sprechen" - -#: config/prefs.php.dist:126 -msgid "" -"How many characters of the entry details in search view should we allow to " -"see?" -msgstr "" -"Wieviele Zeichen sollen bei den Eintragdetails in der Suchansicht gezeigt " -"werden?" - -#: config/prefs.php.dist:156 -msgid "How many decimal digits should we round marks to?" -msgstr "Auf wieviele Stellen sollen die Noten gerundet werden?" - -#: config/schools.php.dist:86 -msgid "Imagination" -msgstr "Vorstellungsvermögen" - -#: lib/School.php:121 lib/School.php:125 lib/School.php:136 lib/School.php:137 -#: lib/School.php:143 -msgid "Interdisciplinary" -msgstr "Fächerübergreifend" - -#: templates/list/headers.inc:60 config/prefs.php.dist:90 -#: config/prefs.php.dist:103 -msgid "Last Entry" -msgstr "Letzter Eintrag" - -#: data.php:64 -msgid "Lastname" -msgstr "Nachname" - -#: lib/Skoli.php:494 config/prefs.php.dist:33 -msgid "List Classes" -msgstr "Klassen anzeigen" - -#: lib/School.php:102 -msgid "List with custom marks separated by comma (best mark first)" -msgstr "Kommagetrennte Liste mit eigenen Noten (beste Note zuerst)" - -#: templates/list/headers.inc:80 config/prefs.php.dist:52 -#: config/prefs.php.dist:68 -msgid "Location" -msgstr "Ort" - -#: templates/classes/list.php:2 classes/index.php:33 -msgid "Manage Classes" -msgstr "Klassen-Verwaltung" - -#: lib/Skoli.php:311 lib/Forms/Entry.php:97 lib/Forms/Entry.php:119 -#: lib/Forms/Entry.php:123 lib/Forms/Entry.php:128 -msgid "Mark" -msgstr "Note" - -#: templates/list/headers.inc:64 config/prefs.php.dist:91 -#: config/prefs.php.dist:104 -msgid "Mark average" -msgstr "Notendurchschnitt" - -#: lib/Forms/Entry.php:119 -msgid "Mark in numbers" -msgstr "Note in Zahlen" - -#: lib/Forms/Entry.php:123 -msgid "Mark in percent" -msgstr "Note in Prozent" - -#: data.php:102 search.php:105 config/prefs.php.dist:22 -msgid "Marks" -msgstr "Noten" - -#: config/schools.php.dist:85 -msgid "Mathematics" -msgstr "Mathematik" - -#: lib/Block/tree_menu.php:3 -msgid "Menu List" -msgstr "Menüliste" - -#: config/schools.php.dist:109 -msgid "Motivation to learn and dedication" -msgstr "Lernmotivation und Einsatz" - -#: config/schools.php.dist:92 -msgid "Music" -msgstr "Musik" - -#: list.php:14 -msgid "My Classes" -msgstr "Meine Klassen" - -#: templates/panel.inc:53 -msgid "My Classes:" -msgstr "Meine Klassen:" - -#: templates/list/headers.inc:56 lib/Forms/EditClass.php:58 -#: lib/Forms/CreateClass.php:57 lib/Forms/CreateClass.php:146 -#: config/prefs.php.dist:65 config/prefs.php.dist:102 -msgid "Name" -msgstr "Name" - -#: config/schools.php.dist:91 -msgid "Nature-Human-Environment" -msgstr "Natur-Mensch-Mitwelt" - -#: templates/list/students.inc:5 templates/list/classes.inc:5 -#: templates/list/headers.inc:41 lib/Block/tree_menu.php:25 -#: config/prefs.php.dist:34 -msgid "New Entry" -msgstr "Neuer Eintrag" - -#: data.php:21 -msgid "No classes are currently available. Export is disabled." -msgstr "" -"Zur Zeit sind keine Klassen verfügbar. Export steht nicht zur Verfügung." - -#: search.php:17 -msgid "No classes are currently available. Searching is disabled." -msgstr "" -"Zur Zeit sind keine Klassen verfügbar. Die Suche steht nicht zur Verfügung." - -#: templates/list/footers.inc:4 -msgid "No classes match" -msgstr "Keine Treffer" - -#: templates/search/footers.inc:4 -msgid "No entries match" -msgstr "Keine Treffer" - -#: data.php:133 search.php:167 -msgid "Not excused" -msgstr "Unentschuldigt" - -#: lib/Skoli.php:312 lib/Forms/Entry.php:100 lib/Forms/Entry.php:146 -msgid "Objective" -msgstr "Beobachtung" - -#: data.php:112 search.php:109 -msgid "Objectives" -msgstr "Beobachtungen" - -#: data.php:125 search.php:162 -msgid "Open" -msgstr "Offen" - -#: data.php:79 -msgid "Open outcomes" -msgstr "Offene Lernziele" - -#: lib/Skoli.php:313 lib/Forms/Entry.php:103 lib/Forms/Entry.php:150 -msgid "Outcome" -msgstr "Lernziel" - -#: data.php:122 search.php:113 -msgid "Outcomes" -msgstr "Lernziele" - -#: templates/entry/delete.inc:7 -msgid "Permanently delete this entry?" -msgstr "Diesen Eintrag unwiederbringlich löschen?" - -#: lib/Forms/DeleteClass.php:51 -msgid "Permission denied" -msgstr "Zugriff verweigert" - -#: list.php:56 add.php:17 -msgid "Please create a new Class first." -msgstr "Bitte erstellen Sie zuerst eine neue Klasse." - -#: config/schools.php.dist:89 -msgid "Problem solving behavior" -msgstr "Problemlöseverhalten" - -#: lib/Forms/EditClass.php:54 lib/Forms/CreateClass.php:53 -msgid "Properties" -msgstr "Eigenschaften" - -#: config/schools.php.dist:82 config/schools.php.dist:98 -#: config/schools.php.dist:104 -msgid "Reading" -msgstr "Lesen" - -#: lib/Forms/DeleteClass.php:37 -#, php-format -msgid "" -"Really delete the class \"%s\"? This cannot be undone and all data on this " -"class will be permanently removed." -msgstr "" -"Die Klasse \"%s\" wirklich löschen? Dieser Vorgang kann nicht rückgängig " -"gemacht werden, und alle Daten in dieser Klasse werden endgültig gelöscht." - -#: templates/search/criteria.inc:39 -msgid "Reset to Defaults" -msgstr "Zurücksetzen" - -#: config/schools.php.dist:53 -msgid "Sample school" -msgstr "Beispiel Schule" - -#: templates/panel.inc:71 lib/Forms/EditClass.php:125 lib/Forms/Entry.php:166 -msgid "Save" -msgstr "Speichern" - -#: lib/Forms/EditClass.php:70 -msgid "School" -msgstr "Schule" - -#: lib/Forms/EditClass.php:63 lib/Forms/CreateClass.php:67 -msgid "School Specific Settings" -msgstr "Schulabhängige Einstellungen" - -#: config/schools.php.dist:75 -msgid "Schoolhouse 1" -msgstr "Schulhaus 1" - -#: config/schools.php.dist:76 -msgid "Schoolhouse 2" -msgstr "Schulhaus 2" - -#: lib/Forms/CreateClass.php:74 -msgid "Schools" -msgstr "Schulen" - -#: search.php:124 templates/search/criteria.inc:38 -#: templates/search/header.inc:4 templates/list/header.inc:3 -#: lib/Block/tree_menu.php:44 config/prefs.php.dist:35 -msgid "Search" -msgstr "Suche" - -#: templates/search/criteria.inc:9 -msgid "Search Criterias" -msgstr "Suchkriterien" - -#: templates/search/header.inc:3 -msgid "Search Result" -msgstr "Suchergebnisse" - -#: templates/panel.inc:38 -msgid "Search for Classes:" -msgstr "Nach Klassen suchen:" - -#: templates/search/criteria.inc:13 -msgid "Search in" -msgstr "Suchen in" - -#: list.php:86 -#, php-format -msgid "Search: Results for \"%s\"" -msgstr "Suche: Ergebnisse für \"%s\"" - -#: templates/data/export.inc:26 -msgid "Select a student or the whole class to export:" -msgstr "Wählen Sie einen Studenten oder die ganze Klasse zum Exportieren:" - -#: templates/data/export.inc:17 -msgid "Select the class to export from:" -msgstr "Wählen Sie die Klasse die exportiert werden soll" - -#: config/prefs.php.dist:54 -msgid "Select the columns that should be shown in the class list view:" -msgstr "" -"Wählen Sie die Spalten, die in der Listenansicht der Klassen angezeigt " -"werden sollen:" - -#: config/prefs.php.dist:93 -msgid "Select the columns that should be shown in the student list view:" -msgstr "" -"Wählen Sie die Spalten, die in der Listenansicht der Studierenden angezeigt " -"werden sollen:" - -#: templates/data/export.inc:9 -msgid "Select the export format:" -msgstr "Wählen Sie das Exportformat:" - -#: config/prefs.php.dist:36 -msgid "Select the view to display after login:" -msgstr "Wählen Sie die Ansicht aus, die beim Start angezeigt werden soll:" - -#: templates/list/headers.inc:76 config/prefs.php.dist:51 -#: config/prefs.php.dist:67 -msgid "Semester" -msgstr "Semester" - -#: templates/list/headers.inc:52 config/prefs.php.dist:49 -#: config/prefs.php.dist:64 -msgid "Semester End" -msgstr "Semesterende" - -#: templates/list/headers.inc:48 config/prefs.php.dist:48 -#: config/prefs.php.dist:63 -msgid "Semester Start" -msgstr "Semesterstart" - -#: templates/panel.inc:62 -msgid "Shared Classes:" -msgstr "Gemeinsame Klassen:" - -#: templates/list/students.inc:13 -#, php-format -msgid "Show \"%s\"" -msgstr "\"%s\" anzeigen" - -#: config/prefs.php.dist:179 -msgid "Show class list options panel?" -msgstr "Kasten mit Klassenlisteninstellungen anzeigen?" - -#: config/prefs.php.dist:188 -msgid "Show students in the class list?" -msgstr "Studierende in der Klassenliste anzeigen?" - -#: templates/panel.inc:43 -msgid "Show students?" -msgstr "Studierende anzeigen?" - -#: config/schools.php.dist:87 -msgid "Skills" -msgstr "Kenntnisse, Fertigkeiten" - -#: list.php:51 -msgid "Skoli needs an applications who provides contacts (e.g. turba)." -msgstr "Skoli benötigt eine Applikation mit Kontakten (z.B. turba)." - -#: templates/list/headers.inc:68 -msgid "Sort by Absences" -msgstr "Sortieren nach Abwesenheiten" - -#: templates/list/headers.inc:84 -msgid "Sort by Category" -msgstr "Sortieren nach Kategorie" - -#: templates/search/headers.inc:34 -msgid "Sort by Class" -msgstr "Sortieren nach Klasse" - -#: templates/search/headers.inc:40 -msgid "Sort by Date" -msgstr "Sortieren nach Datum" - -#: templates/list/headers.inc:72 -msgid "Sort by Grade" -msgstr "Sortieren nach Stufe" - -#: templates/list/headers.inc:60 -msgid "Sort by Last Entry" -msgstr "Sortieren nach letztem Eintrag" - -#: templates/list/headers.inc:80 -msgid "Sort by Location" -msgstr "Sortieren nach Ort" - -#: templates/list/headers.inc:64 -msgid "Sort by Mark" -msgstr "Sortieren nach Noten" - -#: templates/list/headers.inc:56 -msgid "Sort by Name" -msgstr "Sortieren nach Name" - -#: templates/list/headers.inc:76 -msgid "Sort by Semester" -msgstr "Sortieren nach Semester" - -#: templates/list/headers.inc:52 -msgid "Sort by Semester End Date" -msgstr "Sortieren nach Semesterenddatum" - -#: templates/list/headers.inc:48 -msgid "Sort by Semester Start Date" -msgstr "Sortieren nach Semesterstartdatum" - -#: templates/search/headers.inc:37 -msgid "Sort by Student Name" -msgstr "Sortieren nach Studierenden" - -#: templates/search/headers.inc:43 -msgid "Sort by Type" -msgstr "Sortieren nach Typ" - -#: config/prefs.php.dist:70 -msgid "Sort classes by:" -msgstr "Klassen sortieren nach:" - -#: config/prefs.php.dist:81 -msgid "Sort direction for classes:" -msgstr "Sortierrichtung für Klassen:" - -#: config/prefs.php.dist:117 -msgid "Sort direction for students:" -msgstr "Sortierrichtung für Studierende:" - -#: config/prefs.php.dist:106 -msgid "Sort students by:" -msgstr "Studierende sortieren nach:" - -#: config/schools.php.dist:93 -msgid "Sport" -msgstr "Sport" - -#: templates/search/headers.inc:37 lib/Forms/Entry.php:78 -#: lib/Forms/Entry.php:80 -msgid "Student" -msgstr "Studierender" - -#: lib/Forms/EditClass.php:77 lib/Forms/EditClass.php:90 -#: lib/Forms/EditClass.php:123 lib/Forms/CreateClass.php:90 -#: lib/Forms/CreateClass.php:103 lib/Forms/CreateClass.php:136 -msgid "Students" -msgstr "Studierende" - -#: templates/data/export.inc:12 -msgid "Tab separated values (TSV)" -msgstr "Tabgetrennte Werte (TSV)" - -#: config/schools.php.dist:97 config/schools.php.dist:103 -msgid "Talking" -msgstr "Sprechen" - -#: config/schools.php.dist:112 -msgid "Teamwork and autonomy" -msgstr "Zusammenarbeit und Selbstständigkeit" - -#: lib/Driver.php:36 -msgid "The School backend is not currently available." -msgstr "Der Schuleserver ist zur Zeit nicht verfügbar." - -#: lib/Driver.php:85 -#, php-format -msgid "The School backend is not currently available: %s" -msgstr "Der Schuleserver ist zur Zeit nicht verfügbar: %s" - -#: classes/create.php:34 -#, php-format -msgid "The class \"%s\" has been created." -msgstr "Die Klasse \"%s\" wurde erstellt." - -#: classes/delete.php:38 -#, php-format -msgid "The class \"%s\" has been deleted." -msgstr "Die Klasse \"%s\" wurde gelöscht." - -#: classes/edit.php:45 -#, php-format -msgid "The class \"%s\" has been renamed to \"%s\"." -msgstr "Die Klasse \"%s\" wurde nach \"%s\" umbenannt." - -#: classes/edit.php:47 -#, php-format -msgid "The class \"%s\" has been saved." -msgstr "Die Klasse \"%s\" wurde gespeichert." - -#: entry.php:76 -#, php-format -msgid "The entry for \"%s\" has been deleted." -msgstr "Der Eintrag \"%s\" wurde gelöscht." - -#: entry.php:61 -#, php-format -msgid "The entry for \"%s\" has been saved." -msgstr "Der Eintrag für \"%s\" wurde gespeichert." - -#: add.php:30 -#, php-format -msgid "The new entry for \"%s\" has been added." -msgstr "Der neue Eintrag für \"%s\" wurde hinzugefügt." - -#: lib/Forms/CreateClass.php:147 -msgid "" -"The substitutions %c, %g or %s will be replaced automatically by the class, " -"grade respectively semester name." -msgstr "" -"Die Substitutionen %c, %g oder %s werden automatisch mit der Klasse (class), " -"Stufe (grade) bzw. dem Semester (semester) ersetzt." - -#: templates/list/empty.inc:2 -msgid "There are no classes matching the current criteria." -msgstr "Es gibt keine Klassen, die den Suchkriterien entsprechen." - -#: templates/search/empty.inc:2 -msgid "There are no entries matching the current criteria." -msgstr "Es wurden keine passenden Einträge gefunden." - -#: entry.php:74 -#, php-format -msgid "There was an error deleting this entry: %s" -msgstr "Beim Löschen des Eintrags ist ein Fehler aufgetreten: %s" - -#: data.php:154 -msgid "There were no entries to export." -msgstr "Es konnten keine Einträge zum Exportieren gefunden werden." - -#: lib/Forms/Entry.php:116 -msgid "Title" -msgstr "Titel" - -#: templates/search/headers.inc:43 lib/Forms/Entry.php:108 -msgid "Type" -msgstr "Typ" - -#: lib/Forms/DeleteClass.php:58 -#, php-format -msgid "Unable to delete \"%s\": %s" -msgstr "\"%s\" kann nicht gelöscht werden: %s" - -#: lib/Driver.php:88 -#, php-format -msgid "Unable to load the definition of %s." -msgstr "Der %s-Treiber konnte nicht geladen werden." - -#: lib/Forms/EditClass.php:164 -#, php-format -msgid "Unable to save class \"%s\": %s" -msgstr "Die Klasse \"%s\" kann nicht gespeichert werden: %s" - -#: templates/list/classes.inc:47 lib/Skoli.php:746 lib/Skoli.php:747 -#: lib/Skoli.php:761 lib/Skoli.php:762 -msgid "Unfiled" -msgstr "Nicht zugeordnet" - -#: lib/Forms/Entry.php:33 -msgid "Update Entry" -msgstr "Eintrag aktualisieren" - -#: entry.php:86 -msgid "View" -msgstr "Anzeigen" - -#: templates/list/students.inc:27 -#, php-format -msgid "View Entries for \"%s\"" -msgstr "Einträge anzeigen für \"%s\"" - -#: templates/list/classes.inc:25 -#, php-format -msgid "View Entries in \"%s\"" -msgstr "Einträge anzeigen in \"%s\"" - -#: templates/search/entries.inc:21 -msgid "View Entry" -msgstr "Eintrag anzeigen" - -#: lib/Forms/Entry.php:134 -msgid "Weight" -msgstr "Gewichtung" - -#: config/prefs.php.dist:138 -msgid "When a new class is created should we also create a new contact list?" -msgstr "" -"Soll beim Erstellen einer neuen Klasse auch eine neue Kontaktliste angelegt " -"werden?" - -#: data.php:35 -msgid "Whole class" -msgstr "Ganze Klasse" - -#: config/schools.php.dist:83 config/schools.php.dist:99 -#: config/schools.php.dist:105 -msgid "Writing" -msgstr "Schreiben" - -#: classes/edit.php:24 -msgid "You are not allowed to change this class." -msgstr "Sie dürfen diese Klasse nicht ändern." - -#: classes/delete.php:26 -msgid "You are not allowed to delete this class." -msgstr "Sie dürfen diese Klasse nicht löschen." - -#: entry.php:30 -msgid "You are not allowed to view this entry." -msgstr "Sie dürfen diesen Eintrag nicht ansehen." - -#: classes/create.php:21 -msgid "You don't have access to any valid addressbook." -msgstr "Sie haben keinen Zugriff auf ein gültiges Adressbuch." - -#: templates/panel.inc:48 -msgid "[Manage Classes]" -msgstr "[Klassen verwalten]" - -#: lib/Skoli.php:504 -msgid "_Export" -msgstr "_Exportieren" - -#: lib/Skoli.php:496 -msgid "_New Entry" -msgstr "_Neuer Eintrag" - -#: lib/Skoli.php:500 -msgid "_Search" -msgstr "_Suche" - -#: templates/search/criteria.inc:21 -msgid "and" -msgstr "und" - -#: templates/search/criteria.inc:35 -msgid "and for Entries with:" -msgstr "und für Einträge mit:" - -#: data.php:160 templates/data/export.inc:1 -msgid "class.csv" -msgstr "klasse.csv" - -#: data.php:164 -msgid "class.tsv" -msgstr "klasse.tsv" - -#: templates/search/criteria.inc:25 -msgid "for" -msgstr "für" - -#: lib/Block/tree_menu.php:35 -#, php-format -msgid "in %s" -msgstr "in %s" diff --git a/skoli/locale/de/help.xml b/skoli/locale/de/help.xml deleted file mode 100644 index d645bd4ed..000000000 --- a/skoli/locale/de/help.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Skoli Übersicht - Was ist Skoli? - - Skoli ist ein einfaches Verwaltungsmodul für Lehrpersonen. Mehrere - Kontakte (Studierende) werden zu einer Klasse zusammengefasst. Zu - jedem Studierenden können anschließend Noten, Beobachtungen, Lernziele - und Absenzen eingetragen werden. Neben einer Suchfunktion bietet Skoli - auch eine Exportmöglichkeit im CSV und TSV Format. - - - - diff --git a/skoli/locale/en/help.xml b/skoli/locale/en/help.xml deleted file mode 100644 index 0d50ff3b0..000000000 --- a/skoli/locale/en/help.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Skoli Overview - What is Skoli? - - Skoli is a simple administrative module for teachers. Several - contacts (students) will be summarized to a class. To each - student one can then enter marks, objectives, outcomes and - absences. Besides offering a search function Skoli also offers - an export option in the CSV and TSV formats. - - - - diff --git a/skoli/locale/skoli.pot b/skoli/locale/skoli.pot deleted file mode 100644 index 8a75ca85e..000000000 --- a/skoli/locale/skoli.pot +++ /dev/null @@ -1,996 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Horde Project -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: dev@lists.horde.org\n" -"POT-Creation-Date: 2010-08-17 17:46+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: config/schools.php.dist:55 -msgid "1. class" -msgstr "" - -#: config/schools.php.dist:64 -msgid "1. term" -msgstr "" - -#: config/schools.php.dist:56 -msgid "2. class" -msgstr "" - -#: config/schools.php.dist:69 -msgid "2. term" -msgstr "" - -#: config/schools.php.dist:57 -msgid "3. class" -msgstr "" - -#: config/schools.php.dist:58 -msgid "4. class" -msgstr "" - -#: config/schools.php.dist:59 -msgid "5. class" -msgstr "" - -#: config/schools.php.dist:60 -msgid "6. class" -msgstr "" - -#: lib/Skoli.php:314 lib/Forms/Entry.php:106 lib/Forms/Entry.php:156 -msgid "Absence" -msgstr "" - -#: lib/Forms/Entry.php:156 -msgid "Absence in number of lessons" -msgstr "" - -#: data.php:130 search.php:117 templates/list/headers.inc:68 -#: config/prefs.php.dist:92 config/prefs.php.dist:105 -msgid "Absences" -msgstr "" - -#: data.php:69 -msgid "Absences without valid excuse" -msgstr "" - -#: lib/Driver.php:66 -#, php-format -msgid "Access for class \"%s\" is denied" -msgstr "" - -#: lib/Forms/Entry.php:166 -msgid "Add" -msgstr "" - -#: lib/Forms/Entry.php:33 -msgid "Add Entry" -msgstr "" - -#: lib/Forms/EditClass.php:79 lib/Forms/EditClass.php:82 -#: lib/Forms/CreateClass.php:92 lib/Forms/CreateClass.php:95 -msgid "Address Book" -msgstr "" - -#: search.php:102 -msgid "All Types" -msgstr "" - -#: search.php:66 -msgid "All classes" -msgstr "" - -#: search.php:75 -msgid "All students" -msgstr "" - -#: config/schools.php.dist:88 -msgid "Appliance" -msgstr "" - -#: config/prefs.php.dist:79 config/prefs.php.dist:115 -msgid "Ascending" -msgstr "" - -#: config/prefs.php.dist:135 -msgid "Ask every time" -msgstr "" - -#: config/prefs.php.dist:137 -msgid "Automatically create a new contact list" -msgstr "" - -#: lib/Forms/DeleteClass.php:39 lib/Forms/DeleteClass.php:45 -msgid "Cancel" -msgstr "" - -#: templates/list/headers.inc:84 lib/Forms/EditClass.php:61 -#: lib/Forms/CreateClass.php:60 config/prefs.php.dist:53 -#: config/prefs.php.dist:69 -msgid "Category" -msgstr "" - -#: templates/classes/list.php:28 classes/index.php:29 -msgid "Change Permissions" -msgstr "" - -#: config/prefs.php.dist:16 -msgid "Change your settings for automatically create contact lists." -msgstr "" - -#: config/prefs.php.dist:9 -msgid "Change your sorting and display options." -msgstr "" - -#: lib/School.php:92 lib/School.php:99 lib/School.php:128 lib/School.php:142 -#: lib/School.php:148 lib/School.php:164 lib/School.php:167 -#: lib/Forms/EditClass.php:70 lib/Forms/EditClass.php:82 -#: lib/Forms/Entry.php:61 lib/Forms/Entry.php:128 lib/Forms/CreateClass.php:74 -#: lib/Forms/CreateClass.php:95 -msgid "Choose:" -msgstr "" - -#: data.php:62 templates/classes/list.php:16 templates/search/headers.inc:34 -#: lib/Forms/Entry.php:61 -msgid "Class" -msgstr "" - -#: templates/classes/list.php:13 -msgid "Class List" -msgstr "" - -#: templates/panel.inc:32 templates/panel.inc:33 -msgid "Classes" -msgstr "" - -#: templates/search/header.inc:8 templates/list/header.inc:7 -msgid "Close Search" -msgstr "" - -#: templates/data/export.inc:11 -msgid "Comma separated values (CSV)" -msgstr "" - -#: lib/Forms/Entry.php:152 lib/Forms/Entry.php:161 -msgid "Comment" -msgstr "" - -#: data.php:125 search.php:162 -msgid "Completed" -msgstr "" - -#: data.php:78 -msgid "Completed outcomes" -msgstr "" - -#: lib/Forms/Entry.php:151 -msgid "Completed?" -msgstr "" - -#: config/schools.php.dist:110 -msgid "Concentration, attention, perseverance" -msgstr "" - -#: config/schools.php.dist:94 -msgid "Construct" -msgstr "" - -#: lib/Forms/CreateClass.php:139 -msgid "Contact List" -msgstr "" - -#: config/prefs.php.dist:15 -msgid "Contact Lists" -msgstr "" - -#: lib/Forms/Entry.php:179 -msgid "Couldn't add the new entry." -msgstr "" - -#: lib/Forms/EditClass.php:159 lib/Forms/CreateClass.php:200 -msgid "Couldn't add the selected students to the class." -msgstr "" - -#: lib/Skoli.php:276 lib/Forms/CreateClass.php:226 -#, php-format -msgid "Couldn't create the contact list \"%s\"." -msgstr "" - -#: entry.php:59 -#, php-format -msgid "Couldn't update this entry: %s" -msgstr "" - -#: lib/Forms/CreateClass.php:156 -msgid "Create" -msgstr "" - -#: lib/Forms/CreateClass.php:51 -msgid "Create Class" -msgstr "" - -#: lib/Forms/CreateClass.php:141 -msgid "Create Contact List?" -msgstr "" - -#: templates/classes/list.php:8 -msgid "Create a new Class" -msgstr "" - -#: lib/School.php:83 -msgid "Custom format:" -msgstr "" - -#: config/schools.php.dist:46 -msgid "Custom school" -msgstr "" - -#: templates/search/headers.inc:40 lib/Forms/Entry.php:86 -msgid "Date" -msgstr "" - -#: config/prefs.php.dist:23 -msgid "Define a format for marks" -msgstr "" - -#: entry.php:91 templates/classes/list.php:30 templates/entry/delete.inc:8 -#: classes/index.php:30 lib/Forms/DeleteClass.php:39 -msgid "Delete" -msgstr "" - -#: lib/Forms/DeleteClass.php:34 -#, php-format -msgid "Delete %s" -msgstr "" - -#: config/prefs.php.dist:80 config/prefs.php.dist:116 -msgid "Descending" -msgstr "" - -#: lib/Forms/EditClass.php:59 lib/Forms/CreateClass.php:58 -msgid "Description" -msgstr "" - -#: config/prefs.php.dist:8 -msgid "Display Options" -msgstr "" - -#: config/prefs.php.dist:136 -msgid "Don't create contact lists" -msgstr "" - -#: entry.php:88 templates/classes/list.php:26 classes/index.php:28 -msgid "Edit" -msgstr "" - -#: templates/list/classes.inc:13 -#, php-format -msgid "Edit \"%s\"" -msgstr "" - -#: lib/Forms/EditClass.php:50 -#, php-format -msgid "Edit %s" -msgstr "" - -#: templates/search/headers.inc:31 templates/list/headers.inc:44 -msgid "Edit Class" -msgstr "" - -#: entry.php:94 templates/search/entries.inc:5 -msgid "Edit Entry" -msgstr "" - -#: templates/list/headers.inc:89 -msgid "Edit categories and colors" -msgstr "" - -#: config/schools.php.dist:101 -msgid "English" -msgstr "" - -#: config/prefs.php.dist:147 -msgid "" -"Enter a default name for new contact lists.
    NOTE: You can use %c, %g or " -"%s as substitution for the class, grade respectively semester name." -msgstr "" - -#: config/prefs.php.dist:165 -msgid "" -"Enter some custom marks and separate them by comma (best mark first).
    NOTE: You also need to choose \"Custom settings\" above." -msgstr "" - -#: templates/search/headers.inc:46 -msgid "Entry" -msgstr "" - -#: entry.php:100 -#, php-format -msgid "Entry for \"%s\"" -msgstr "" - -#: entry.php:23 -msgid "Entry not found." -msgstr "" - -#: lib/School.php:36 -#, php-format -msgid "Error loading the school \"%s\" from template." -msgstr "" - -#: data.php:133 search.php:167 -msgid "Excused" -msgstr "" - -#: data.php:68 -msgid "Excused absences" -msgstr "" - -#: lib/Forms/Entry.php:157 -msgid "Excused?" -msgstr "" - -#: config/schools.php.dist:111 -msgid "Exercise processing" -msgstr "" - -#: templates/data/export.inc:32 -msgid "Export" -msgstr "" - -#: data.php:171 templates/data/export.inc:5 -msgid "Export Classes" -msgstr "" - -#: data.php:63 -msgid "Firstname" -msgstr "" - -#: lib/School.php:81 -msgid "Format in numbers" -msgstr "" - -#: lib/School.php:82 -msgid "Format in percent" -msgstr "" - -#: config/schools.php.dist:95 -msgid "French" -msgstr "" - -#: config/prefs.php.dist:7 config/prefs.php.dist:14 config/prefs.php.dist:21 -msgid "General Options" -msgstr "" - -#: lib/Forms/EditClass.php:56 lib/Forms/CreateClass.php:55 -msgid "General Settings" -msgstr "" - -#: config/schools.php.dist:80 -msgid "German" -msgstr "" - -#: templates/list/headers.inc:72 config/prefs.php.dist:50 -#: config/prefs.php.dist:66 -msgid "Grade" -msgstr "" - -#: config/schools.php.dist:96 config/schools.php.dist:102 -msgid "Hearing" -msgstr "" - -#: config/schools.php.dist:81 -msgid "Hearing and Talking" -msgstr "" - -#: config/prefs.php.dist:126 -msgid "" -"How many characters of the entry details in search view should we allow to " -"see?" -msgstr "" - -#: config/prefs.php.dist:156 -msgid "How many decimal digits should we round marks to?" -msgstr "" - -#: config/schools.php.dist:86 -msgid "Imagination" -msgstr "" - -#: lib/School.php:121 lib/School.php:125 lib/School.php:136 lib/School.php:137 -#: lib/School.php:143 -msgid "Interdisciplinary" -msgstr "" - -#: templates/list/headers.inc:60 config/prefs.php.dist:90 -#: config/prefs.php.dist:103 -msgid "Last Entry" -msgstr "" - -#: data.php:64 -msgid "Lastname" -msgstr "" - -#: lib/Skoli.php:494 config/prefs.php.dist:33 -msgid "List Classes" -msgstr "" - -#: lib/School.php:102 -msgid "List with custom marks separated by comma (best mark first)" -msgstr "" - -#: templates/list/headers.inc:80 config/prefs.php.dist:52 -#: config/prefs.php.dist:68 -msgid "Location" -msgstr "" - -#: templates/classes/list.php:2 classes/index.php:33 -msgid "Manage Classes" -msgstr "" - -#: lib/Skoli.php:311 lib/Forms/Entry.php:97 lib/Forms/Entry.php:119 -#: lib/Forms/Entry.php:123 lib/Forms/Entry.php:128 -msgid "Mark" -msgstr "" - -#: templates/list/headers.inc:64 config/prefs.php.dist:91 -#: config/prefs.php.dist:104 -msgid "Mark average" -msgstr "" - -#: lib/Forms/Entry.php:119 -msgid "Mark in numbers" -msgstr "" - -#: lib/Forms/Entry.php:123 -msgid "Mark in percent" -msgstr "" - -#: data.php:102 search.php:105 config/prefs.php.dist:22 -msgid "Marks" -msgstr "" - -#: config/schools.php.dist:85 -msgid "Mathematics" -msgstr "" - -#: lib/Block/tree_menu.php:3 -msgid "Menu List" -msgstr "" - -#: config/schools.php.dist:109 -msgid "Motivation to learn and dedication" -msgstr "" - -#: config/schools.php.dist:92 -msgid "Music" -msgstr "" - -#: list.php:14 -msgid "My Classes" -msgstr "" - -#: templates/panel.inc:53 -msgid "My Classes:" -msgstr "" - -#: templates/list/headers.inc:56 lib/Forms/EditClass.php:58 -#: lib/Forms/CreateClass.php:57 lib/Forms/CreateClass.php:146 -#: config/prefs.php.dist:65 config/prefs.php.dist:102 -msgid "Name" -msgstr "" - -#: config/schools.php.dist:91 -msgid "Nature-Human-Environment" -msgstr "" - -#: templates/list/students.inc:5 templates/list/classes.inc:5 -#: templates/list/headers.inc:41 lib/Block/tree_menu.php:25 -#: config/prefs.php.dist:34 -msgid "New Entry" -msgstr "" - -#: data.php:21 -msgid "No classes are currently available. Export is disabled." -msgstr "" - -#: search.php:17 -msgid "No classes are currently available. Searching is disabled." -msgstr "" - -#: templates/list/footers.inc:4 -msgid "No classes match" -msgstr "" - -#: templates/search/footers.inc:4 -msgid "No entries match" -msgstr "" - -#: data.php:133 search.php:167 -msgid "Not excused" -msgstr "" - -#: lib/Skoli.php:312 lib/Forms/Entry.php:100 lib/Forms/Entry.php:146 -msgid "Objective" -msgstr "" - -#: data.php:112 search.php:109 -msgid "Objectives" -msgstr "" - -#: data.php:125 search.php:162 -msgid "Open" -msgstr "" - -#: data.php:79 -msgid "Open outcomes" -msgstr "" - -#: lib/Skoli.php:313 lib/Forms/Entry.php:103 lib/Forms/Entry.php:150 -msgid "Outcome" -msgstr "" - -#: data.php:122 search.php:113 -msgid "Outcomes" -msgstr "" - -#: templates/entry/delete.inc:7 -msgid "Permanently delete this entry?" -msgstr "" - -#: lib/Forms/DeleteClass.php:51 -msgid "Permission denied" -msgstr "" - -#: list.php:56 add.php:17 -msgid "Please create a new Class first." -msgstr "" - -#: config/schools.php.dist:89 -msgid "Problem solving behavior" -msgstr "" - -#: lib/Forms/EditClass.php:54 lib/Forms/CreateClass.php:53 -msgid "Properties" -msgstr "" - -#: config/schools.php.dist:82 config/schools.php.dist:98 -#: config/schools.php.dist:104 -msgid "Reading" -msgstr "" - -#: lib/Forms/DeleteClass.php:37 -#, php-format -msgid "" -"Really delete the class \"%s\"? This cannot be undone and all data on this " -"class will be permanently removed." -msgstr "" - -#: templates/search/criteria.inc:39 -msgid "Reset to Defaults" -msgstr "" - -#: config/schools.php.dist:53 -msgid "Sample school" -msgstr "" - -#: templates/panel.inc:71 lib/Forms/EditClass.php:125 lib/Forms/Entry.php:166 -msgid "Save" -msgstr "" - -#: lib/Forms/EditClass.php:70 -msgid "School" -msgstr "" - -#: lib/Forms/EditClass.php:63 lib/Forms/CreateClass.php:67 -msgid "School Specific Settings" -msgstr "" - -#: config/schools.php.dist:75 -msgid "Schoolhouse 1" -msgstr "" - -#: config/schools.php.dist:76 -msgid "Schoolhouse 2" -msgstr "" - -#: lib/Forms/CreateClass.php:74 -msgid "Schools" -msgstr "" - -#: search.php:124 templates/search/criteria.inc:38 -#: templates/search/header.inc:4 templates/list/header.inc:3 -#: lib/Block/tree_menu.php:44 config/prefs.php.dist:35 -msgid "Search" -msgstr "" - -#: templates/search/criteria.inc:9 -msgid "Search Criterias" -msgstr "" - -#: templates/search/header.inc:3 -msgid "Search Result" -msgstr "" - -#: templates/panel.inc:38 -msgid "Search for Classes:" -msgstr "" - -#: templates/search/criteria.inc:13 -msgid "Search in" -msgstr "" - -#: list.php:86 -#, php-format -msgid "Search: Results for \"%s\"" -msgstr "" - -#: templates/data/export.inc:26 -msgid "Select a student or the whole class to export:" -msgstr "" - -#: templates/data/export.inc:17 -msgid "Select the class to export from:" -msgstr "" - -#: config/prefs.php.dist:54 -msgid "Select the columns that should be shown in the class list view:" -msgstr "" - -#: config/prefs.php.dist:93 -msgid "Select the columns that should be shown in the student list view:" -msgstr "" - -#: templates/data/export.inc:9 -msgid "Select the export format:" -msgstr "" - -#: config/prefs.php.dist:36 -msgid "Select the view to display after login:" -msgstr "" - -#: templates/list/headers.inc:76 config/prefs.php.dist:51 -#: config/prefs.php.dist:67 -msgid "Semester" -msgstr "" - -#: templates/list/headers.inc:52 config/prefs.php.dist:49 -#: config/prefs.php.dist:64 -msgid "Semester End" -msgstr "" - -#: templates/list/headers.inc:48 config/prefs.php.dist:48 -#: config/prefs.php.dist:63 -msgid "Semester Start" -msgstr "" - -#: templates/panel.inc:62 -msgid "Shared Classes:" -msgstr "" - -#: templates/list/students.inc:13 -#, php-format -msgid "Show \"%s\"" -msgstr "" - -#: config/prefs.php.dist:179 -msgid "Show class list options panel?" -msgstr "" - -#: config/prefs.php.dist:188 -msgid "Show students in the class list?" -msgstr "" - -#: templates/panel.inc:43 -msgid "Show students?" -msgstr "" - -#: config/schools.php.dist:87 -msgid "Skills" -msgstr "" - -#: list.php:51 -msgid "Skoli needs an applications who provides contacts (e.g. turba)." -msgstr "" - -#: templates/list/headers.inc:68 -msgid "Sort by Absences" -msgstr "" - -#: templates/list/headers.inc:84 -msgid "Sort by Category" -msgstr "" - -#: templates/search/headers.inc:34 -msgid "Sort by Class" -msgstr "" - -#: templates/search/headers.inc:40 -msgid "Sort by Date" -msgstr "" - -#: templates/list/headers.inc:72 -msgid "Sort by Grade" -msgstr "" - -#: templates/list/headers.inc:60 -msgid "Sort by Last Entry" -msgstr "" - -#: templates/list/headers.inc:80 -msgid "Sort by Location" -msgstr "" - -#: templates/list/headers.inc:64 -msgid "Sort by Mark" -msgstr "" - -#: templates/list/headers.inc:56 -msgid "Sort by Name" -msgstr "" - -#: templates/list/headers.inc:76 -msgid "Sort by Semester" -msgstr "" - -#: templates/list/headers.inc:52 -msgid "Sort by Semester End Date" -msgstr "" - -#: templates/list/headers.inc:48 -msgid "Sort by Semester Start Date" -msgstr "" - -#: templates/search/headers.inc:37 -msgid "Sort by Student Name" -msgstr "" - -#: templates/search/headers.inc:43 -msgid "Sort by Type" -msgstr "" - -#: config/prefs.php.dist:70 -msgid "Sort classes by:" -msgstr "" - -#: config/prefs.php.dist:81 -msgid "Sort direction for classes:" -msgstr "" - -#: config/prefs.php.dist:117 -msgid "Sort direction for students:" -msgstr "" - -#: config/prefs.php.dist:106 -msgid "Sort students by:" -msgstr "" - -#: config/schools.php.dist:93 -msgid "Sport" -msgstr "" - -#: templates/search/headers.inc:37 lib/Forms/Entry.php:78 -#: lib/Forms/Entry.php:80 -msgid "Student" -msgstr "" - -#: lib/Forms/EditClass.php:77 lib/Forms/EditClass.php:90 -#: lib/Forms/EditClass.php:123 lib/Forms/CreateClass.php:90 -#: lib/Forms/CreateClass.php:103 lib/Forms/CreateClass.php:136 -msgid "Students" -msgstr "" - -#: templates/data/export.inc:12 -msgid "Tab separated values (TSV)" -msgstr "" - -#: config/schools.php.dist:97 config/schools.php.dist:103 -msgid "Talking" -msgstr "" - -#: config/schools.php.dist:112 -msgid "Teamwork and autonomy" -msgstr "" - -#: lib/Driver.php:36 -msgid "The School backend is not currently available." -msgstr "" - -#: lib/Driver.php:85 -#, php-format -msgid "The School backend is not currently available: %s" -msgstr "" - -#: classes/create.php:34 -#, php-format -msgid "The class \"%s\" has been created." -msgstr "" - -#: classes/delete.php:38 -#, php-format -msgid "The class \"%s\" has been deleted." -msgstr "" - -#: classes/edit.php:45 -#, php-format -msgid "The class \"%s\" has been renamed to \"%s\"." -msgstr "" - -#: classes/edit.php:47 -#, php-format -msgid "The class \"%s\" has been saved." -msgstr "" - -#: entry.php:76 -#, php-format -msgid "The entry for \"%s\" has been deleted." -msgstr "" - -#: entry.php:61 -#, php-format -msgid "The entry for \"%s\" has been saved." -msgstr "" - -#: add.php:30 -#, php-format -msgid "The new entry for \"%s\" has been added." -msgstr "" - -#: lib/Forms/CreateClass.php:147 -msgid "" -"The substitutions %c, %g or %s will be replaced automatically by the class, " -"grade respectively semester name." -msgstr "" - -#: templates/list/empty.inc:2 -msgid "There are no classes matching the current criteria." -msgstr "" - -#: templates/search/empty.inc:2 -msgid "There are no entries matching the current criteria." -msgstr "" - -#: entry.php:74 -#, php-format -msgid "There was an error deleting this entry: %s" -msgstr "" - -#: data.php:154 -msgid "There were no entries to export." -msgstr "" - -#: lib/Forms/Entry.php:116 -msgid "Title" -msgstr "" - -#: templates/search/headers.inc:43 lib/Forms/Entry.php:108 -msgid "Type" -msgstr "" - -#: lib/Forms/DeleteClass.php:58 -#, php-format -msgid "Unable to delete \"%s\": %s" -msgstr "" - -#: lib/Driver.php:88 -#, php-format -msgid "Unable to load the definition of %s." -msgstr "" - -#: lib/Forms/EditClass.php:164 -#, php-format -msgid "Unable to save class \"%s\": %s" -msgstr "" - -#: templates/list/classes.inc:47 lib/Skoli.php:746 lib/Skoli.php:747 -#: lib/Skoli.php:761 lib/Skoli.php:762 -msgid "Unfiled" -msgstr "" - -#: lib/Forms/Entry.php:33 -msgid "Update Entry" -msgstr "" - -#: entry.php:86 -msgid "View" -msgstr "" - -#: templates/list/students.inc:27 -#, php-format -msgid "View Entries for \"%s\"" -msgstr "" - -#: templates/list/classes.inc:25 -#, php-format -msgid "View Entries in \"%s\"" -msgstr "" - -#: templates/search/entries.inc:21 -msgid "View Entry" -msgstr "" - -#: lib/Forms/Entry.php:134 -msgid "Weight" -msgstr "" - -#: config/prefs.php.dist:138 -msgid "When a new class is created should we also create a new contact list?" -msgstr "" - -#: data.php:35 -msgid "Whole class" -msgstr "" - -#: config/schools.php.dist:83 config/schools.php.dist:99 -#: config/schools.php.dist:105 -msgid "Writing" -msgstr "" - -#: classes/edit.php:24 -msgid "You are not allowed to change this class." -msgstr "" - -#: classes/delete.php:26 -msgid "You are not allowed to delete this class." -msgstr "" - -#: entry.php:30 -msgid "You are not allowed to view this entry." -msgstr "" - -#: classes/create.php:21 -msgid "You don't have access to any valid addressbook." -msgstr "" - -#: templates/panel.inc:48 -msgid "[Manage Classes]" -msgstr "" - -#: lib/Skoli.php:504 -msgid "_Export" -msgstr "" - -#: lib/Skoli.php:496 -msgid "_New Entry" -msgstr "" - -#: lib/Skoli.php:500 -msgid "_Search" -msgstr "" - -#: templates/search/criteria.inc:21 -msgid "and" -msgstr "" - -#: templates/search/criteria.inc:35 -msgid "and for Entries with:" -msgstr "" - -#: data.php:160 templates/data/export.inc:1 -msgid "class.csv" -msgstr "" - -#: data.php:164 -msgid "class.tsv" -msgstr "" - -#: templates/search/criteria.inc:25 -msgid "for" -msgstr "" - -#: lib/Block/tree_menu.php:35 -#, php-format -msgid "in %s" -msgstr "" diff --git a/skoli/scripts/.htaccess b/skoli/scripts/.htaccess deleted file mode 100755 index 3a4288278..000000000 --- a/skoli/scripts/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/skoli/scripts/sql/skoli.sql b/skoli/scripts/sql/skoli.sql deleted file mode 100755 index 99a430fbf..000000000 --- a/skoli/scripts/sql/skoli.sql +++ /dev/null @@ -1,81 +0,0 @@ -CREATE TABLE skoli_classes_students ( - class_id VARCHAR(255) NOT NULL, - student_id VARCHAR(255) NOT NULL -); - -CREATE INDEX skoli_classlist_idx ON skoli_classes_students (class_id); -CREATE INDEX skoli_studentlist_idx ON skoli_classes_students (student_id); - -CREATE TABLE skoli_objects ( - object_id VARCHAR(32) NOT NULL, - object_owner VARCHAR(255) NOT NULL, - object_uid VARCHAR(255) NOT NULL, - class_id VARCHAR(255) NOT NULL, - student_id VARCHAR(255) NOT NULL, - object_time INT NOT NULL, - object_type VARCHAR(255) NOT NULL, - PRIMARY KEY (object_id) -); - -CREATE INDEX skoli_objectlist_idx ON skoli_objects (object_owner); -CREATE INDEX skoli_uid_idx ON skoli_objects (object_uid); -CREATE INDEX skoli_classlist_idx ON skoli_objects (class_id); -CREATE INDEX skoli_studentlist_idx ON skoli_objects (student_id); - -CREATE TABLE skoli_object_attributes ( - object_id VARCHAR(32) NOT NULL, - attr_name VARCHAR(50) NOT NULL, - attr_value VARCHAR(255), - PRIMARY KEY (object_id, attr_name) -); -CREATE INDEX skoli_object_attributes_object_idx ON skoli_object_attributes (object_id); - -CREATE TABLE skoli_shares ( - share_id INT NOT NULL, - share_name VARCHAR(255) NOT NULL, - share_owner VARCHAR(32) NOT NULL, - share_flags SMALLINT NOT NULL DEFAULT 0, - perm_creator SMALLINT NOT NULL DEFAULT 0, - perm_default SMALLINT NOT NULL DEFAULT 0, - perm_guest SMALLINT NOT NULL DEFAULT 0, - attribute_name VARCHAR(255) NOT NULL, - attribute_desc VARCHAR(255), - attribute_school VARCHAR(255) NOT NULL, - attribute_grade VARCHAR(255), - attribute_semester VARCHAR(255), - attribute_start INT NOT NULL, - attribute_end INT NOT NULL, - attribute_category VARCHAR(255) NULL, - attribute_location VARCHAR(255), - attribute_marks VARCHAR(255), - attribute_address_book VARCHAR(255) NOT NULL, - PRIMARY KEY (share_id) -); - -CREATE INDEX skoli_shares_share_name_idx ON skoli_shares (share_name); -CREATE INDEX skoli_shares_share_owner_idx ON skoli_shares (share_owner); -CREATE INDEX skoli_shares_perm_creator_idx ON skoli_shares (perm_creator); -CREATE INDEX skoli_shares_perm_default_idx ON skoli_shares (perm_default); -CREATE INDEX skoli_shares_perm_guest_idx ON skoli_shares (perm_guest); -CREATE INDEX skoli_shares_attribute_category_idx ON skoli_shares (attribute_category); -CREATE INDEX skoli_shares_attribute_address_book_idx ON skoli_shares (attribute_address_book); - -CREATE TABLE skoli_shares_groups ( - share_id INT NOT NULL, - group_uid VARCHAR(255) NOT NULL, - perm SMALLINT NOT NULL -); - -CREATE INDEX skoli_shares_groups_share_id_idx ON skoli_shares_groups (share_id); -CREATE INDEX skoli_shares_groups_group_uid_idx ON skoli_shares_groups (group_uid); -CREATE INDEX skoli_shares_groups_perm_idx ON skoli_shares_groups (perm); - -CREATE TABLE skoli_shares_users ( - share_id INT NOT NULL, - user_uid VARCHAR(255) NOT NULL, - perm SMALLINT NOT NULL -); - -CREATE INDEX skoli_shares_users_share_id_idx ON skoli_shares_users (share_id); -CREATE INDEX skoli_shares_users_user_uid_idx ON skoli_shares_users (user_uid); -CREATE INDEX skoli_shares_users_perm_idx ON skoli_shares_users (perm); diff --git a/skoli/search.php b/skoli/search.php deleted file mode 100644 index 848cc83bd..000000000 --- a/skoli/search.php +++ /dev/null @@ -1,187 +0,0 @@ - - */ - -require_once dirname(__FILE__) . '/lib/base.php'; - -$classes = Skoli::listClasses(); - -/* If there are no valid classes, abort. */ -if (count($classes) == 0) { - $notification->push(_("No classes are currently available. Searching is disabled."), 'horde.error'); - require SKOLI_TEMPLATES . '/common-header.inc'; - require SKOLI_TEMPLATES . '/menu.inc'; - require $registry->get('templates', 'horde') . '/common-footer.inc'; - exit; -} - -$actionID = Horde_Util::getFormData('actionID'); - -if (!isset($_SESSION['skoli'])) { - $_SESSION['skoli'] = array(); -} - -if (($classid = Horde_Util::getFormData('class')) !== null) { - $_SESSION['skoli']['search_classid'] = $classid; -} else if (isset($_SESSION['skoli']['search_classid'])) { - $classid = $_SESSION['skoli']['search_classid']; -} -if (($studentid = Horde_Util::getFormData('student')) !== null) { - $_SESSION['skoli']['search_studentid'] = $studentid; -} else if (isset($_SESSION['skoli']['search_studentid'])) { - $studentid = $_SESSION['skoli']['search_studentid']; -} -if (($type = Horde_Util::getFormData('type')) !== null) { - $_SESSION['skoli']['search_type'] = $type; -} else if (isset($_SESSION['skoli']['search_type'])) { - $type = $_SESSION['skoli']['search_type']; -} -if (($search = Horde_Util::getFormData('stext')) !== null) { - $_SESSION['skoli']['search_stext'] = $search; -} else if (isset($_SESSION['skoli']['search_stext'])) { - $search = $_SESSION['skoli']['search_stext']; -} - -/* Sort out the sorting values */ -$sortby = Horde_Util::getFormData('sortby'); -$sortdir = Horde_Util::getFormData('sortdir'); -if ($sortby === null) { - $sortby = SKOLI_SORT_CLASS; -} else if ($sortby == Horde_Util::getFormData('sortby')) { - $sortdir = !$sortdir; -} -if ($sortdir === null) { - $sortdir = SKOLI_SORT_ASCEND; -} - -$class_options = array(); -if (count($classes) > 1) { - $class_options[] = '\n"; -} -foreach ($classes as $key=>$class) { - $class_options[] = '\n"; -} - -$student_options = array(); -$student_options[] = '\n"; -if ($classid == '' || $classid == 'all') { - $studentslist = Skoli::listStudents(null, SKOLI_SORT_NAME, SKOLI_SORT_ASCEND); - $students = array(); - foreach ($studentslist as $val) { - $students = array_merge($students, $val['_students']); - } -} else { - $studentslist = current(Skoli::listStudents($classid, SKOLI_SORT_NAME, SKOLI_SORT_ASCEND)); - $students = $studentslist['_students']; -} -$foundstudent = false; -foreach ($students as $address) { - if ($studentid == $address['student_id']) { - $foundstudent = true; - } - $student_options[] = '\n"; -} -if (!$foundstudent && $studentid != 'all') { - $actionID = ''; - $studentid = ''; - $_SESSION['skoli']['search_studentid'] = $studentid; -} - -$type_options = array(); -$type_options[] = '\n"; -if ($conf['objects']['allow_marks']) { - $type_options[] = '\n"; -} -if ($conf['objects']['allow_objectives']) { - $type_options[] = '\n"; -} -if ($conf['objects']['allow_outcomes']) { - $type_options[] = '\n"; -} -if ($conf['objects']['allow_absences']) { - $type_options[] = '\n"; -} - -Horde::addInlineScript(array( - '$("stext").focus()' -), 'dom'); - -$title = _("Search"); - -Horde::addScriptFile('quickfinder.js', 'horde'); -Horde::addScriptFile('effects.js', 'horde'); -Horde::addScriptFile('redbox.js', 'horde'); -require SKOLI_TEMPLATES . '/common-header.inc'; -require SKOLI_TEMPLATES . '/menu.inc'; -reset($classes); -require SKOLI_TEMPLATES . '/search/criteria.inc'; - -if ($actionID == 'search') { - $params = array($search); - $list = Skoli::listEntries($classid == 'all' ? null : $classid, $studentid == 'all' ? null : $studentid, $type == 'all' ? null : $type, $params, $sortby, $sortdir); - - $dynamic_sort = false; - $params = array('actionID' => 'search'); - $baseurl = Horde_Util::addParameter('search.php', $params); - echo '
    '; - require SKOLI_TEMPLATES . '/search/header.inc'; - if (count($list) > 0) { - require SKOLI_TEMPLATES . '/search/headers.inc'; - foreach ($list as $entry) { - $style = 'linedRow'; - $details = ''; - - switch ($entry['type']) { - case 'mark': - $details = $entry['subject'] . ': ' . $entry['mark'] . - ($classes[$entry['classid']]->get('marks') == 'percent' ? '%' : '') . - ' (' . $entry['weight'] . '), ' . $entry['title']; - break; - - case 'objective': - $details = $entry['category'] . ' (' . $entry['subject'] . '): ' . $entry['objective']; - break; - - case 'outcome': - $details = $entry['outcome'] . ': ' . - (isset($entry['completed']) && $entry['completed'] != '' ? _("Completed") : _("Open")) . - (isset($entry['comment']) && $entry['comment'] != '' ? ', ' . $entry['comment'] : ''); - break; - - case 'absence': - $details = (isset($entry['excused']) && $entry['excused'] != '' ? _("Excused") : _("Not excused")) . - ': ' . $entry['absence'] . - (isset($entry['comment']) && $entry['comment'] != '' ? ', ' . $entry['comment'] : ''); - break; - } - $detailswrapped = Horde_String::wordwrap($details, $prefs->getValue('entry_details_wrap'), '
    ', true); - $entry['details'] = current(explode('
    ', $detailswrapped)); - require SKOLI_TEMPLATES . '/search/entries.inc'; - } - - require SKOLI_TEMPLATES . '/search/footers.inc'; - - if ($dynamic_sort) { - Horde::addScriptFile('tables.js', 'horde'); - } - } else { - require SKOLI_TEMPLATES . '/search/empty.inc'; - } -} - -require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/skoli/templates/classes/list.php b/skoli/templates/classes/list.php deleted file mode 100644 index e1c736bc0..000000000 --- a/skoli/templates/classes/list.php +++ /dev/null @@ -1,35 +0,0 @@ -

    - -

    - -
    -
    - - " /> -
    -
    - - 0): ?> -" cellspacing="0" id="class-list" class="striped sortable"> - - - - - - - - - - - - - - - - - - - - -
     
    get('name')) ?>">">">
    - diff --git a/skoli/templates/common-header.inc b/skoli/templates/common-header.inc deleted file mode 100644 index 11adac711..000000000 --- a/skoli/templates/common-header.inc +++ /dev/null @@ -1,34 +0,0 @@ -getCharset()); - header('Vary: Accept-Language'); -} -?> - - - - -' : '' ?> - -get('name'); -if (!empty($title)) { - $page_title .= ' :: ' . $title; -} - -Horde::outputMetaTags(); -Horde::includeScriptFiles(); - -$bc = $prefs->getValue('show_panel') - ? 'rightPanel' - : ''; - -?> -<?php echo htmlspecialchars($page_title) ?> - - - - - -> diff --git a/skoli/templates/data/export.inc b/skoli/templates/data/export.inc deleted file mode 100644 index 3d81f29d8..000000000 --- a/skoli/templates/data/export.inc +++ /dev/null @@ -1,34 +0,0 @@ -
    "> - - -

    - -

    - -
    -
    -
    - - 1): ?> -
    -
    -
    - - - -
    - -
    -
    -
    - - " class="button" /> -
    -
    diff --git a/skoli/templates/entry/delete.inc b/skoli/templates/entry/delete.inc deleted file mode 100644 index c46ac27d9..000000000 --- a/skoli/templates/entry/delete.inc +++ /dev/null @@ -1,10 +0,0 @@ -
    - - - - -
    -

    - " /> -
    -
    diff --git a/skoli/templates/list/classes.inc b/skoli/templates/list/classes.inc deleted file mode 100644 index c17987c40..000000000 --- a/skoli/templates/list/classes.inc +++ /dev/null @@ -1,49 +0,0 @@ - - - '; - } - ?> - - - '; - } - ?> - - -   - -   - - - 'search', - 'class' => $class['_id'], - 'student' => 'all' - ); - echo Horde::link(Horde_Util::addParameter(Horde::url('search.php'), $params), $label) . htmlspecialchars($class['name']) . ''; - ?> - - -   - -   - -   - -   - -   - -   - - - - diff --git a/skoli/templates/list/empty.inc b/skoli/templates/list/empty.inc deleted file mode 100644 index 3e418aa2e..000000000 --- a/skoli/templates/list/empty.inc +++ /dev/null @@ -1,3 +0,0 @@ -

    - -

    diff --git a/skoli/templates/list/footers.inc b/skoli/templates/list/footers.inc deleted file mode 100644 index a5ef8c968..000000000 --- a/skoli/templates/list/footers.inc +++ /dev/null @@ -1,6 +0,0 @@ - - -

    - -
    -
    diff --git a/skoli/templates/list/header.inc b/skoli/templates/list/header.inc deleted file mode 100644 index 5ad70ecc5..000000000 --- a/skoli/templates/list/header.inc +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/skoli/templates/list/headers.inc b/skoli/templates/list/headers.inc deleted file mode 100644 index f2ce0a8e7..000000000 --- a/skoli/templates/list/headers.inc +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/skoli/templates/list/students.inc b/skoli/templates/list/students.inc deleted file mode 100644 index fa060f0c2..000000000 --- a/skoli/templates/list/students.inc +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/skoli/templates/menu.inc b/skoli/templates/menu.inc deleted file mode 100644 index 319b5c80d..000000000 --- a/skoli/templates/menu.inc +++ /dev/null @@ -1,5 +0,0 @@ - - -notify(array('listeners' => 'status')) ?> diff --git a/skoli/templates/panel.inc b/skoli/templates/panel.inc deleted file mode 100644 index 780145227..000000000 --- a/skoli/templates/panel.inc +++ /dev/null @@ -1,76 +0,0 @@ -getAuth(); -$my_classes = array(); -$shared_classes = array(); -foreach (Skoli::listClasses() as $id => $cl) { - if ($cl->get('owner') && $cl->get('owner') == $current_user) { - $my_classes[$id] = $cl; - } else { - $shared_classes[$id] = $cl; - } -} -?> - -
    - - - - -
    -
    - -

    -

    - -

    -

    - -

    - -getAuth()): ?> -

    - -

    - - - -

    -
      - $cl): ?> -
    • - -
    - - - -

    -
      - $cl): ?> -
    • - -
    - - -

    - " class="button" /> -

    - - -
    -
    diff --git a/skoli/templates/search/criteria.inc b/skoli/templates/search/criteria.inc deleted file mode 100644 index b17bb8f2c..000000000 --- a/skoli/templates/search/criteria.inc +++ /dev/null @@ -1,44 +0,0 @@ - - - - -

    - -

    - -
    - - 1): ?> - - - get('name') ?> - -  - -  -
    - -
    - -
    - - - - width="2%"> -   - width="2%"> -   - > -   - width="2%"> -   - width="2%"> -   - width="2%"> -   - width="2%"> -   - width="2%"> -   - width="2%"> -   - width="10%"> -   - getAuth() && (!$GLOBALS['prefs']->isLocked('categories') || - !$GLOBALS['prefs']->isLocked('category_colors'))) { - $categoryUrl = Horde_Util::addParameter(Horde::getServiceLink('prefs', 'horde'), array('group' => 'categories')); - echo ' ' . Horde::link($categoryUrl, _("Edit categories and colors"), '', '_blank', Horde::popupJs($categoryUrl, array('urlencode' => true)) . 'return false;') . Horde::img('colorpicker.png', _("Edit categories and colors")) . ''; - } - ?> -
    - $class['_id'], 'student'=>$student['__key'])), $label) . Horde::img('add.png', $label) . ''; - } - ?> - - hasMethod('contacts/show')) { - $label = sprintf(_("Show \"%s\""), $student[$conf['addresses']['name_field']]); - $url = $registry->link('contacts/show', array('source' => $class['address_book'], - 'key' => $student['__key'])); - echo Horde::link($url, $label) . Horde::img('user.png', $label) . ''; - } - ?> -    - 'search', - 'class' => $class['_id'], - 'student' => $student['__key'] - ); - echo $treeIcon . ' ' . Horde::link(Horde_Util::addParameter(Horde::url('search.php'), $params), $label) . htmlspecialchars($student[$conf['addresses']['name_field']]) . ''; - ?> -      
    - - - -
    - - - - " /> - " /> -
    -
    - diff --git a/skoli/templates/search/empty.inc b/skoli/templates/search/empty.inc deleted file mode 100644 index 3121ac26f..000000000 --- a/skoli/templates/search/empty.inc +++ /dev/null @@ -1,3 +0,0 @@ -

    - -

    diff --git a/skoli/templates/search/entries.inc b/skoli/templates/search/entries.inc deleted file mode 100644 index f53695f05..000000000 --- a/skoli/templates/search/entries.inc +++ /dev/null @@ -1,27 +0,0 @@ - - - 'EditEntry', - 'entry' => $entry['_id'] - ); - echo Horde::link(Horde_Util::addParameter(Horde::url('entry.php'), $params), $label) . Horde::img('edit.png', $label) . ''; - } - ?> - -   - - 'Entry', - 'entry' => $entry['_id'] - ); - echo Horde::link(Horde_Util::addParameter(Horde::url('entry.php'), $params), _("View Entry")) . htmlspecialchars($entry['student']) . ' '; - ?> - -   -   -   - diff --git a/skoli/templates/search/footers.inc b/skoli/templates/search/footers.inc deleted file mode 100644 index bafb71ee3..000000000 --- a/skoli/templates/search/footers.inc +++ /dev/null @@ -1,6 +0,0 @@ - - -

    - -
    - diff --git a/skoli/templates/search/header.inc b/skoli/templates/search/header.inc deleted file mode 100644 index 71f3659cd..000000000 --- a/skoli/templates/search/header.inc +++ /dev/null @@ -1,11 +0,0 @@ -
    - diff --git a/skoli/templates/search/headers.inc b/skoli/templates/search/headers.inc deleted file mode 100644 index 5d762e3af..000000000 --- a/skoli/templates/search/headers.inc +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/skoli/themes/categoryCSS.php b/skoli/themes/categoryCSS.php deleted file mode 100644 index b3668af65..000000000 --- a/skoli/themes/categoryCSS.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ - -$skoli_authentication = 'none'; -require_once dirname(__FILE__) . '/../lib/base.php'; - -header('Content-Type: text/css'); - -$cManager = new Horde_Prefs_CategoryManager(); - -$colors = $cManager->colors(); -$fgColors = $cManager->fgColors(); -foreach ($colors as $category => $color) { - if ($category == '_unfiled_' || $category == '_default_') { - continue; - } - - $class = '.category' . md5($category); - - echo "$class, .linedRow td$class, .overdue td$class, .closed td$class { " - . 'color: ' . (isset($fgColors[$category]) ? $fgColors[$category] : $fgColors['_default_']) . '; ' - . 'background: ' . $color . '; ' - . "padding: 0 4px; }\n"; -} diff --git a/skoli/themes/graphics/add.png b/skoli/themes/graphics/add.png deleted file mode 100644 index 324f5fd19a626b0cf4b658771ce4abc4e4cea20c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 663 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47?lHjLR^8||Ns9drDga>#RkVF zq~sT67ME2twUpI2CZ?sw<`pJqW@Qx=Hng?ZwYGT&1cXIIc>DMyB_}g7GWh!X{J&E4 zX@%(j57&IXJ@}Xz&e@9PhWP%n=HBV0-|S$pD8_q5qW|37#N!s?OI-~X1v!*Qg-kS1 zD2xb+3l9T2rM|ANthBVGxOmN)H7i!ESiXGuk|j$PE?l@^!Giho=g*rrZ~FA<)22cYTu@MumzS5Do12}Tot2f9nVFfEmX?^9n2?YV6B8329v%`B5*!>H5D?(! z=jZF|>*?v~;o;%n;9zcU4h$Tg_s2AV!IW4MNJ1upHA=Z|X)n zrFZ}Q^)6kpIXkte(m*Nv_RYCTPoD`!I4{{T)%vD&)}KjjhAw)1UC*zED)2HKd%pWq z@LI=N%M@7xw6^EVE4K(tQeiYb^jza`3yVXj@*e>qkYMMAH}^vVU9r2dIj{)78&q Iol`;+0JRbu(EtDd diff --git a/skoli/themes/graphics/favicon.ico b/skoli/themes/graphics/favicon.ico deleted file mode 100644 index c3b82e4f198b2b36c4b34b24336168405ba4510f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 792 zcmZvaOH(qH7%d_k@MjMlb}qeF%pyA-JB$uBfR?sv%h zhQm3)&B7YU*dZ&o57IUTKY?N$Qa&;|nqX)sMkEqtdwZL$tt~b;H`&5hKNN;a1fj|Ji-;dAdLy{ys9uF>; zOU%tldwV+$hXcFaF6P;S)oP`=xfzSaB4%pFXf$Fl7|`qWG&VM()9KJ^wba(uqS0um zuC7k*Rn+kxNFd3wBq$()-r(R6RMsTR?rit@`}(8jAE@qEOS1IR+3NQ81P4x56soI` zd9F9McwPs>S@*6Mi7Xf&Hd%DfdLkE6@^6dx*y|e}89Uot*{RpckR`3@vEjul&*jr+ z?&g(WlF&AqZI0TEW4YIhOVTbvL(>zJRe9q|!JX3MId70!o1YqD e+o3sks;)~c_HV)6Uh!`aqoW@F36jdu0e=AR*WE4v diff --git a/skoli/themes/graphics/minus.png b/skoli/themes/graphics/minus.png deleted file mode 100644 index 32170460cc24a1a1687786fb1e135b84ed80bd21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Wq?nJt4ZpT+GW?9SKZil=2`uU z>uqaqPS|{F(w19Ow%wk;@4?nH&$gX?cHr`hsoQUFIrDV;xo5jCKHqck`Tzg_WoKCg z01Xi?3GxdDa?t?8rrJ9kKxsWs7sn8ZsmTIP%seJS2@XsGjB<>QbqWujCAD#V_*k@I m^G2hM21P~**PYm>Gcg#2@~8j${jM6Qlfl!~&t;ucLK6T0fn84k diff --git a/skoli/themes/graphics/plus.png b/skoli/themes/graphics/plus.png deleted file mode 100644 index 263e356901817a5ace857c6416481a8cc89faedc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Wq?nJt4ZpT+GW?9SKZil=2`uU z>uqaqPS|{F(w19Ow%wk;@4?nH&$gX?cHr`hsoQUFIrDV;xo5jCKHqck`Tzg_WoKCg z01Xi?3GxdDa?t?8rrJ9kKxq$87sn8Z%gF*x%sdt>5)BNY4fE%VFixnOz;HxH;E|xf z6LzLNy|fh!^7`!7(%Qn@%IeHc+}hes+(!b!N}?k;cQW67Sy98yP|(Hueogq5a-f+E Mp00i_>zopr0454z8UO$Q diff --git a/skoli/themes/graphics/search.png b/skoli/themes/graphics/search.png deleted file mode 100644 index 94c47d455e3eb1c758c79da1fd74f37831616196..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 794 zcmV+#1LgdQP)1V6Mdku2@=!r7%xX>^OL z4bEEPwX>aj!!QhRo@4V1vcX^w6#Wji;{!E1;n*IxQSpzntI-#4J_iS-2IpOw-i0Gb zv-ss=j{67X$rJ#OG)=a-xw#|F5SbG^wOYAK$RsEF-S?~YE<&bv-jErbm8EUdGg`Af zzqq(?sBUSVEdW}z>au3Fig8n$z^zU4%JE#PchwLER~eySR-vsF<2u_z?rwz&!2?0% zH=n5!}4wi%I##Uk79|0l8&reNFf~HjsG6j+6@hhUZ zNO<`K1a%T=Y^wKnbapTni)D}dTy2}yTfr;aEGa1|7l|>LoE!&j`(v=#Yn+a diff --git a/skoli/themes/graphics/skoli.png b/skoli/themes/graphics/skoli.png deleted file mode 100644 index 03f96725b1360278cad703e8b9d49b186cc62223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 767 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47&8KVLR^8||NsB1$;s>M>LsOR z_(#PC$0nrY7iAWgX&akXG_{n~HzuZ~$L19#XJ%y;6gITA*R{5(>ggMpn(FB5dj|yg z2L**iM0or7Bqb-GvlYt?@%?DX{L7mAz8UvzOa7f+`ppgoi(K>>gwu>ii+~`^0G3Z!KEc7 zK(mVr3JUV_@^W)?v$M0ava&KWGt<)25)%^>5)xu!Vj?0U!o$NuLPCOrg9Ctm_xJbn z^Yiuf_3`oX^z?Ldb8~fdb#``ka&mHTaImtnvb3}`H#Y}{aFxIsU0_&Olmz(&1GxhM z7;3^LdVp>?=jq}YA|V-j@M@S7qloK8(>L#cKulz!_O>L(Qy&*eB)tAtEBoWv91Z4Q z=`$`}kZ<0>JwqksL7Z-wnC^YGgDtJ!nEyGr`j`byz!9nHBpvbhFFPOd6H%Q@fm)u!9-0*4|$zRi83 zVwb(?)-S@x(fPr$Fv(jp+?oCMf oFz45gwwtUimw0@PCI_^|=eT;^5qrMD2k0{fPgg&ebxsLQ0NiVWaR2}S diff --git a/skoli/themes/graphics/timetable.png b/skoli/themes/graphics/timetable.png deleted file mode 100644 index 3da6e7eb3127e7da3dc716b5b48d52defd5288d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 501 zcmVSisHm;2t@5Z9ySux*yu7`=y}rJ_zrVl2 z!otJD!^+Ca&CSiv&(HtVa@pD0+uPgS-QC{a-rwKe-{0Ti;o;)q;^X7vgww2>+9_7?CtIC?(XjI@9**P@&EAF^78WY^Yird^!E1l_xJbt`T6?#`uqF) zH}@7N0001}Nkl
    - - width="2%"> -   - width="2%"> -   - width="2%"> -   - width="2%"> -   - -   -
  • -' . $news['title'] . ' - ' . $news['abbreviation'] . '... (' . $news['comments'] . ')
    '; -?> -